Perl模块文件:使用STDIN管道传输Slurp

时间:2017-09-11 14:29:08

标签: bash perl 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脚本以允许此操作的最佳方法是什么,同时保留在命令行上使用单个文件的现有功能?

2 个答案:

答案 0 :(得分:1)

要让您的脚本在管道中工作,您可以检查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

答案 1 :(得分:0)

您只需要以下内容:

local $^I = '';

while (<>) {
  s/foo/bar/g; 
  print;
}

这与perl -i -pe's/foo/bar/'基本相同,只是在使用STDIN时不会发出警告。