簡體   English   中英

將來自STDIN的輸入和Perl中的文件組合

[英]Combining Input from STDIN and File in Perl

我想要我的Perl腳本能夠執行此操作

./code1 param1 param2 param3 | perl myperlscript.pl param1 param2

因此,Perl腳本應該接受3個輸入:

  1. 參數1
  2. 參數2
  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刪除param1param2

my $param1 = shift;
my $param2 = shift;

現在,您可以處理從管道輸出的code1使用

while (<>) {
  ...;
}

更通用的解決方案是使用bash流程替代,

perl myperlscript.pl <(./other param1 param2) <(./code1 param1 param2 param3)

這使得othercode1的輸出從命名管道出現

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM