2009-04-16 106 views
4

我有以下代码,它使用'粘贴'和AWK脚本 Perl。如何在Perl中使用paste和awk?

use strict;    
use Data::Dumper;   
use Carp; 
use File::Basename;  

my @files = glob("result/*-*.txt"); 
my $tocheck = $ARGV[0] || "M"; 


foreach my $file (@files ) { 
    my $base = basename($file,".txt"); 
    my @res = `paste <\(awk '\$4 == "M" {sum += \$2 }END{print sum}' $file \) <\(awk '\$4 == "M" {sum += \$3 }END{print sum}' $file\)`; 
    chomp(@res);   
    print "$base $res[0]\n";  
} 

为什么它给出了这样的错误:

#sh: -c: line 1: syntax error near unexpected token `(' 
#sh: -c: line 1: `paste <(awk '$4 == "M" {sum += $2 }END{print sum}' result/9547_1-S_aureus.txt) <(awk '$4 == "M" {sum += $3 }END{print sum}' 
#result/9547_1-S_aureus.txt) 

什么是做正确的方法是什么?

+2

perl 1.0被认为是AWK的*替换*。牢记未来。 – 2009-04-16 07:52:30

回答

11

不能完全确定,如果这是你的脚本的正确解释,因为似乎是一个大量的死/无用的代码有,但肯定是有没有必要去产卵粘贴或awk来做到这一点:

#!/usr/bin/perl 
use warnings; 
use strict; 
use File::Basename; 

my @files = glob ("result/*-*.txt"); 

foreach my $file (@files) { 
    open (FILE, $file) or die "open $file: $!\n"; 
    # You seem to be summing the 2nd and 3rd columns if the 4th is "M" 
    my ($col1, $col2) = (0, 0); 
    while (<FILE>) { 
     my @cols = split /\s+/; 
     if ($cols[3] eq "M") { 
      # Perl uses 0-based arrays, unlike awk 
      $col1 += $cols[1]; 
      $col2 += $cols[2]; 
     } 
    } 
    close FILE; 
    printf "%s %d\n", basename ($file), $col1; 
} 
3

为了解决这个错误,Perl的反引用显式地使用/ bin/sh来运行该命令。您的/ bin/sh不是bash,并且不理解“<(进程替换)”语法。

我完全同意从Perl调用awk是愚蠢的。

1

可以简化下面的命令吗?

my $inputString = "paste <\(grep \"target:\" $gTestFile | awk '{print \$4,\$5,\$6,\$7,\$8,\$10,\$11,\$12,\$15,\$16,\$17}'\) $preFile"; 

my @combinedOutput = `$inputString`;