带有 STDIN 管道的 Perl 模块 File:Slurp
Perl module File:Slurp with STDIN piped
我刚刚尝试使用以下 Perl 脚本通过 File::Slurp 模块进行一些文本替换。它适用于在命令行 (BASH) 作为参数给出的单个文件。
#!/opt/local/bin/perl -w
use File::Slurp qw( edit_file_lines );
foreach my $argnum (0 .. $#ARGV) {
edit_file_lines {
s/foo/bar/g;
print $_
}
$ARGV[$argnum];
}
我想改变它以应对管道(即 STDIN),以便它可以在一系列管道操作的中间:
例如:
command blah|....|my-perl-script|sort|uniq|wc....
更改 Perl 脚本以允许这样做的最佳方法是什么,同时保留在命令行上处理单个文件的现有能力?
要让您的脚本在管道中运行,您可以检查 STDIN
是否连接到 tty
:
use strict;
use warnings;
use File::Slurp qw( edit_file_lines );
sub my_edit_func { s/foo/bar/g; print $_ }
if ( !(-t STDIN) ) {
while(<>) { my_edit_func }
}
else {
foreach my $argnum (0 .. $#ARGV) {
edit_file_lines { my_edit_func } $ARGV[$argnum];
}
}
有关 -t
文件测试运算符的详细信息,请参阅 perldoc -X
。
您只需要以下内容:
local $^I = '';
while (<>) {
s/foo/bar/g;
print;
}
这与perl -i -pe's/foo/bar/'
基本相同,只是在使用STDIN时不发出警告。
我刚刚尝试使用以下 Perl 脚本通过 File::Slurp 模块进行一些文本替换。它适用于在命令行 (BASH) 作为参数给出的单个文件。
#!/opt/local/bin/perl -w
use File::Slurp qw( edit_file_lines );
foreach my $argnum (0 .. $#ARGV) {
edit_file_lines {
s/foo/bar/g;
print $_
}
$ARGV[$argnum];
}
我想改变它以应对管道(即 STDIN),以便它可以在一系列管道操作的中间: 例如:
command blah|....|my-perl-script|sort|uniq|wc....
更改 Perl 脚本以允许这样做的最佳方法是什么,同时保留在命令行上处理单个文件的现有能力?
要让您的脚本在管道中运行,您可以检查 STDIN
是否连接到 tty
:
use strict;
use warnings;
use File::Slurp qw( edit_file_lines );
sub my_edit_func { s/foo/bar/g; print $_ }
if ( !(-t STDIN) ) {
while(<>) { my_edit_func }
}
else {
foreach my $argnum (0 .. $#ARGV) {
edit_file_lines { my_edit_func } $ARGV[$argnum];
}
}
有关 -t
文件测试运算符的详细信息,请参阅 perldoc -X
。
您只需要以下内容:
local $^I = '';
while (<>) {
s/foo/bar/g;
print;
}
这与perl -i -pe's/foo/bar/'
基本相同,只是在使用STDIN时不发出警告。