从文件中打印与第二列中的模式列表匹配的单行

print single line from file that matches list of patterns in the second column

编辑:我在 Linux 集群中工作。

我有一个很大的文件,在第一列中列出了一个 ID,第二列是原始文件中第 4-5-6 列中复制的列的组合。输入文件如下所示:

1       1:71:T:C        0       71      C       T
1       1:71:T:A        0       71      A       T
1       1:72:GTGTGTGTT:G        0       72      G       GTGTGTGTT
1       1:75:T:C        0       75      C       T
1       1:75:T:*        0       75      *       T
1       1:76:GTGTT:G    0       76      G       GTGTT
1       1:76:GTGTT:*    0       76      *       GTGTT
1       1:83:C:CAT      0       83      CAT     C
1       1:87:CGT:C      0       87      C       CGT
1       1:87:C:CGTGTGT  0       87      CGTGTGT C
U       U:19874536:G:A  0       19874536        A       G
U       U:19874560:G:A  0       19874560        A       G
U       U:19874575:C:T  0       19874575        T       C
U       U:19874577:T:G  0       19874577        G       T
U       U:19874587:CA:C 0       19874587        C       CA
U       U:19874587:CAA:C        0       19874587        C       CAA
U       U:19874602:C:T  0       19874602        T       C
U       U:19876478:T:C  0       19876478        C       T
U       U:19876534:C:A  0       19876534        A       C
U       U:19876568:T:C  0       19876568        C       T
22      X:29:G:GT       0       29      G       GT
22      X:96:T:A        0       96      A       T
22      X:146:A:G       0       146     G       A
22      X:167:A:T       0       167     T       A
22      X:168:T:C       0       168     C       T
22      X:244:C:T       0       244     T       C
22      X:253:C:A       0       253     A       C
22      X:254:C:A       0       254     A       C
22      X:330:G:T       0       330     T       G
22      X:371:GGCGTTTACGT:G     0       371     G       GGCGTTTACGT
.
.
.

我正在尝试检查第 1 列 (ID) 如何与第 2 列中的原始 ID 匹配,所以我只想打印与原始 ID 列表匹配的第一行(在第二列中).我希望这很清楚!我看到 ,我认为它应该可以帮助我,但我不熟悉 awk 并且我不知道如何编辑它所以匹配仅指 ID(在 ' :') 在第 2 列中。

编辑:预期输出:

 1       1:71:T:C        0       71      C       T
 U       U:19874536:G:A  0       19874536        A       G
 22      X:29:G:GT       0       29      G       GT
 .
 .
 .

Perl 解决方案:

perl -F'/[\s:]+/' -lane 'BEGIN { %matches = ( 22 => "X", ); } print if ( ( $F[0] eq $F[1] || $F[1] eq $matches{ $F[0] } ) && !$seen{ $F[0] }++ ); ' infile > outfile

Perl one-liner 使用这些命令行标志:
-e :告诉 Perl 查找代码 in-line,而不是在文件中。
-n :一次循环输入一行,默认分配给 $_
-l : 在执行代码 in-line 之前去除输入行分隔符(默认情况下在 *NIX 上为 "\n"),并在打印时附加它。
-a : 在空格或 -F 选项中指定的正则表达式上将 $_ 拆分为数组 @F
-F'/[\s:]+/' :在空白处或 : 处拆分为 @F,重复 1 次或多次,而不是在空白处。

%matches = ( 22 => "X", ); - 创建哈希 [​​=24=],它将匹配的 ID 从第 1 列映射到第 2 列。为了速度,它被放置在 BEGIN { ... } 块中,它只执行一次在脚本的开头,在后续代码之前是 运行,即每个输入行都是 运行。
!$seen{ $F[0] }++ :仅当每个值在第一列中第一次出现时才为真。

另请参见:
perldoc perlrun: how to execute the Perl interpreter: command line switches