[英]Combining Input from STDIN and File in Perl
我想要我的Perl腳本能夠執行此操作
./code1 param1 param2 param3 | perl myperlscript.pl param1 param2
因此,Perl腳本應該接受3個輸入:
./code1 param1 param2 param3
輸出 我的Perl代碼中有此內容,但出現了問題:
my $param1 = $ARGV[0] || "control.fst";
my $param2 = $ARGV[1] || "target.fst";
my @control_header = `grep ">" $param1`;
my @target_header = `grep ">" $param2`;
# Later to do something with those arrays
while (<>) {
# do something again
}
我知道我可以為./code1
臨時輸出。 但是由於輸出很大,所以我希望將其通過管道傳輸。 請提出正確的做法。
@ARGV
不為空時, <>
運算符將從那里指定的文件中讀取。 @ARGV
用盡后,將從STDIN
繼續讀取。
如果在讀取@control_header
和@target_header
數組后顯式清空@ARGV
,則程序應會按預期運行。 或者,您可以使用<STDIN>
從STDIN
顯式讀取。
但是我相信最好使用Perl從文件參數中讀取所需的信息。 該程序演示了這個想法
use strict;
use warnings;
my $param1 = shift || 'control.fst';
my @control_header = do {
open my $fh, '<', $param1 or die qq(Unable to open file "$param1": $!);
grep />/, <$fh>;
};
my $param2 = shift || 'target.fst';
my @target_header = do {
open my $fh, '<', $param2 or die qq(Unable to open file "$param2": $!);
grep />/, <$fh>;
};
while (<STDIN>) {
# do something again
}
您的情況下,請從@ARGV
刪除param1
和param2
。
my $param1 = shift;
my $param2 = shift;
現在,您可以處理從管道輸出的code1
使用
while (<>) {
...;
}
更通用的解決方案是使用bash流程替代,如
perl myperlscript.pl <(./other param1 param2) <(./code1 param1 param2 param3)
這使得other
和code1
的輸出從命名管道出現
while (<>) {
...;
}
會很開心的過程。
更完善的代碼是:
#!/usr/bin/perl
use strict;
use warnings;
my $param1 = $ARGV[0] || "control.fst";
my $param2 = $ARGV[1] || "target.fst";
my @control_header;
my @target_header;
open FH, "<$param1" or die;
map { push @control_header, $1 if /^(.*?>.*?)[\n\r]*$/ } (<FH>);
close FH;
open FH, "<$param2" or die;
map { push @target_header, $1 if /^(.*?>.*?)[\n\r]*$/ } (<FH>);
close FH;
...
while (<STDIN>) {
...
}
有兩個選項供您選擇。
1)閱讀STDIN
while (<STDIN>) {
chomp();
# do something again
}
2)從您的Perl腳本中調用第一個程序並處理其輸出。 參見Perl Cookbook中的食譜16.05 。
open(PRG,"./code1 param1 param2 param3|") or die $!;
while (<PRG>) {
chomp();
# do something again
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.