2017-09-11 119 views
0

我剛剛嘗試使用下面的Perl腳本來使用File :: Slurp模塊進行一些文本替換。對於在命令行(BASH)中作爲參數給出的單個文件,它工作正常。Perl模塊文件:Slurp與STDIN管道

#!/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腳本,以允許這一點,同時保留現有的能力,在命令行上使用單個文件?

+0

是的,但沒有發現解決我的具體問題。使用File :: Slurp模塊的約束排除了諸如https://stackoverflow.com/questions/3138649/programmatically-read-from-stdin-or-input-file-in-perl?rq=1 – Tim

+0

['edit_file_lines '等同於Perl的'-pi'命令行選項](https://metacpan.org/pod/File::Slurp#edit_file,-edit_file_lines)。你不明白'-pi'的作用或者是否有一些額外的原因,你必須使用'File :: Slurp'完成這個任務? – mob

+1

我編輯了您的問題,將縮進添加到您的代碼中。不客氣,但請下次自己做。如果你要求一大羣人閱讀並理解你的代碼,那麼確保它儘可能地簡單易懂。 –

回答

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

+0

這回答了這個問題,因爲它允許我使用File :: Slurp包(或者一般來說,其他)。 – Tim

0

所有你需要的是這樣的:

local $^I = ''; 

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

這基本上是因爲perl -i -pe's/foo/bar/'相同的,除了使用標準輸入時不會發出警告。

+0

我知道這個構造,我的問題需要使用File :: Slurp包。但來自@melpomene的評論讓我覺得我可能需要擺脫這個包。 – Tim