【问题标题】:Matching pattern across multiple files: perl or grep?跨多个文件的匹配模式:perl 还是 grep?
【发布时间】:2012-04-10 15:50:58
【问题描述】:

我有一个 pattern.txt 文件,如下所示:

2gqt+FAD+A+601   2i0z+FAD+A+501
1n1e+NDE+A+400   2qzl+IXS+A+449
1llf+F23+A+800   1y0g+8PP+A+320
1ewf+PC1+A+577   2a94+AP0+A+336
2ydx+TXP+E+1339   3g8i+RO7+A+1
1gvh+HEM+A+1398   1v9y+HEM+A+1140
2i0z+FAD+A+501   3m2r+F43+A+1
1h6d+NDP+A+500   3rt4+LP5+C+501
1w07+FAD+A+1660   2pgn+FAD+A+612
2qd1+PP9+A+701   3gsi+FAD+A+902

还有一个名为 data 的文件(大小约为 8gb),其中包含这样的行。

2gqt+FAD+A+601   2i0z+FAD+A+501    0.874585  0.785412
1n1e+NDE+A+400   2qzl+IXS+A+449    0.145278  0.589452
1llf+F23+A+800   1y0g+8PP+A+320    0.784512  0.341786
1ewf+PC1+A+577   2a94+AP0+A+336    0.362542  0.784785
2ydx+TXP+E+1339   3g8i+RO7+A+1     0.251452  0.365298
1gvh+HEM+A+1398   1v9y+HEM+A+1140  0.784521  0.625893
2i0z+FAD+A+501   3m2r+F43+A+1      0.369856  0.354842
1h6d+NDP+A+500   3rt4+LP5+C+501    0.925478  0.365895
1w07+FAD+A+1660   2pgn+FAD+A+612   0.584785  0.325863
2qd1+PP9+A+701   3gsi+FAD+A+902    0.874526  0.125453

然而,数据文件并不像上面给出的那么简单。该文件的大尺寸是由于其中大约有 18000 行,它们从每行第一列的字符串开始。即 18000 行以 2gqt+FAD+A+601 开头,然后是 18000 行以 1n1e+NDE+A+400 开头。但是只有一个这样的行与给定的模式匹配,如 pattern.txt

我正在尝试将 pattern.txt 中的行与数据匹配并希望打印出来:

2gqt+FAD+A+601   2i0z+FAD+A+501 0.785412
1n1e+NDE+A+400   2qzl+IXS+A+449 0.589452
1llf+F23+A+800   1y0g+8PP+A+320 0.341786
1ewf+PC1+A+577   2a94+AP0+A+336 0.784785  
2ydx+TXP+E+1339   3g8i+RO7+A+1  0.365298
1gvh+HEM+A+1398   1v9y+HEM+A+114 0 0.625893
2i0z+FAD+A+501   3m2r+F43+A+1 0.354842
1h6d+NDP+A+500   3rt4+LP5+C+501 0.365895
1w07+FAD+A+1660   2pgn+FAD+A+612 0.325863
2qd1+PP9+A+701   3gsi+FAD+A+902 0.125453

到目前为止,我在 perl 中使用了一些东西,如下所示:

use warnings;
open AS, "combi_output_2_fixed.txt";
open AQ, "NAMES.txt";
@arr=<AS>;
@arr1=<AQ>;
foreach $line(@arr)
{
    @split=split(' ',$line);
    foreach $line1(@arr1)
    {
     @split1=split(' ',$line1);
     if($split[0] eq $split1[0] && $split[1] eq $split1[1])
     { print $split1[0],"\t",$split1[1],"\t",$split1[3],"\n";}
   }

}
close AQ;
close AS;

这样做会耗尽整个内存:并显示内存不足错误消息.. 我知道这可以使用 grep 来完成。但不知道怎么做。 谁能告诉我如何使用 grep -F 在不使用整个内存的情况下做到这一点?

谢谢。

【问题讨论】:

    标签: grep


    【解决方案1】:

    pattern.txt 是否适合内存?

    如果是这样,您可以使用grep -F -f pattern.txt data.txt 之类的命令来匹配 data.txt 中的行与模式。不过,您会得到完整的行,并且需要额外的处理才能仅获取第二列数字。

    或者您可以修复 Perl 脚本。内存不足的原因是因为您将 8gb 文件完全读取到内存中,而您可以像 grep 一样逐行处理它。对于 8GB 文件,您应该使用如下代码:

    open FH, "<", "data.txt";
    while ($line = <FH>) { 
        # check $line against list of patterns ...
    }
    

    【讨论】:

    • 是的。 pattern.txt 只是一个 276kb 的文件。
    【解决方案2】:

    试试这个

    grep "`more pattern.txt`" data.txt | awk -F' ' '{ print $1 " "  $2 " " $4}'
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-01-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-07
      相关资源
      最近更新 更多