使用bash代码组合两个共享PATTERN的文本

时间:2012-03-28 16:12:56

标签: bash design-patterns

我有以下两个文本文件:

第一个:

chr10   1000    1001    DEL 2.4807  chr10   7443    8978
chr10   1005    1008    DEL 1.2799  chr10   7321    8778

第二个:

chr13  3456  6746  chr10 7443   8978
chr13  6453  8767  chr10 7321   8778

我们可以看到他们分享一种模式:

chr10   7443    8978
chr10   7321    8778

因此,基于这种模式,我如何将它们组合成:

chr10   1000    1001    DEL 2.4807  chr10   7443    8978 chr13  3456  6746
chr10   1005    1008    DEL 1.2799  chr10   7321    8778 chr13  6453  8767

感谢

编辑: 我一直在尝试grep:

cat text1|grep -f `cat text2|awk '{print $4"\t"$5"\t"$6}'`

但它不起作用

1 个答案:

答案 0 :(得分:3)

你可以用awk one-liner做三个字段。这是一个证据:

[ghoti@pc ~]$ cat file1
chr10   1000    1001    DEL 2.4807  chr10   7443    8978
chr10   1005    1008    DEL 1.2799  chr10   7321    8778
[ghoti@pc ~]$ cat file2
chr13  3456  6746  chr10 7443   8978
chr13  6453  8767  chr10 7321   8778
[ghoti@pc ~]$ awk 'NR == FNR { what[$(NF-2),$(NF-1),$(NF)] = $0; next; } { printf("%s %s\n", what[$(NF-2),$(NF-1),$(NF)], $0); }' file1 file2
chr10   1000    1001    DEL 2.4807  chr10   7443    8978 chr13  3456  6746  chr10 7443   8978
chr10   1005    1008    DEL 1.2799  chr10   7321    8778 chr13  6453  8767  chr10 7321   8778
[ghoti@pc ~]$ 

如果您想要其他顺序的文件,只需更改printf()中$0what[]的顺序。

请注意,这假设您可以将第一个文件的全部内容加载到内存中的数组中。可能不应该用于具有数百万行的文件,但这完全取决于您运行它的系统。

这是如何运作的?

awk脚本有两个主要部分,每个部分都是花括号。如果NR(到目前为止读取的所有数据的当前记录号)与FNR(当前文件中的记录号)匹配,则第一部分仅运行。换句话说,它仅作用于第一个文件。第一个文件在一个关联数组中加载到内存中,该关联数组的下标是该行的最后三个字段。

第二部分在第一部分之后作用于每个后续文件。它只是打印当前行,但在它前面加上与当前行的最后三个字段匹配的数组内容(在第一部分中匹配)。