unix - 从文件中打印单行 matches 第二列中的模式列表

编辑:我在 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
.
.
.

我正在尝试检查第一列(ID)如何与第二列中的原始 ID 匹配,所以我只想打印 matches 原始 ID 列表的第一行(在第二列中)。我希望这很清楚!我看到 https://stackoverflow.com/questions/50263627/how-to-extract-only-first-line-that-matches-each-pattern-from-a-file,我认为它应该能够帮助我,但我不熟悉 awk 并且我不知道如何编辑它所以 match 仅指第二列中的 ID(在“:”之前)。

编辑:预期输出:

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
 .
 .
 .

回答1

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 单行器使用这些命令行标志:

-e:告诉 Perl 查找内联代码,而不是在文件中。

-n:循环一次输入一行,默认将其分配给 $_

-l :在执行代码之前剥离输入行分隔符(默认为 *NIX 上的 "\n")行,并在打印时附加它。

-a : 将 $_ 拆分为数组 @F 上的空白或 -F 选项中指定的正则表达式。

-F'/[\s:]+/' :在空格或 : 上拆分为 @F,重复 1 次或多次,而不是在空格上。

%matches = ( 22 => "X", ); - 创建哈希 %matches,它将匹配的 ID 从第 1 列映射到第 2 列。为了加快速度,这被放置在 BEGIN { ... } 块中,该块仅在脚本开头执行一次,在后续代码之前运行,它针对每个输入行运行。

!$seen{ $F[0] }++ :仅对于第一列中每个 value 的第一次出现为 true。

还请参见:

https://perldoc.perl.org/perlrun.html#Command-Switches

相似文章