比较不同文件中的两列,并为共享项添加数据 - UNIX

时间:2014-05-07 10:54:14

标签: bash unix awk

我一直在论坛中搜索我的问题的解决方案,但不幸的是我没有成功。我在bash中很绿;因此,我非常感谢任何与之前的问题/讨论相关的建议

我有两个文件:

文件1

    Ada     ada
    Ada     ada
    Ada     aidB
    Ada     alkA
    Ada     alkB
    Ada     alkB
    AdiY    adiA
    AdiY    gadA

file2的

    NP_414557.1     insL1
    NP_414559.1     mokC
    YP_025292.1     hokC
    NP_414560.1     nhaA
    NP_414561.1     nhaR
    NP_414562.1     insB1
    NP_414563.1     insA
    NP_414564.1     rpsT

我想根据第二列比较 file1 file2 。如果对象相同,我想将文本附加到 file2 中第1列中的文本,相对于 file1 中第三列中的特定共享条目。

预期产量: 文件1

    PhoB  caiT  NP_414580.1     
    PhoP  caiE  NP_414581.1     
    PhoP  caiB  NP_414582.1 

请将报告的内容视为示例。

我正在努力尝试从前一个问题调整代码:

Compare two files of different columns and print different columns

awk 'NR==FNR{a[$1]=$2 ; next }$2 in a {$1=$1 FS a[$2]print}' file1 file2

非常感谢您的时间和帮助。

最佳。

2 个答案:

答案 0 :(得分:2)

正如@fedorqui评论的那样,您的示例输入/输出不一致。我认为这应该可以解决这个问题:

awk 'NR==FNR{a[$2]=$0; next} a[$2]>0{print a[$2],$1}' file1 file2

文件1:

A alice
B bob
C carol
D dan

file2的:

1 dan
2 alice
3 carol
4 bob

输出:

$ awk 'NR==FNR{a[$2]=$0} NR>FNR && a[$2]>0{print a[$2],$1}' file1 file2
D dan 1
A alice 2
C carol 3
B bob 4

可以使用sort -k选择的任何列对输出进行排序。分解awk代码:

  • NR==FNR{a[$2]=$0; next} - NR是一个awk变量,其中包含到目前为止处理的总行数。 FNR类似,但只包含当前文件的进程行数,因此这个条件实际上意味着只对第一个输入文件"执行此操作。关联操作将整行($0)存储在关联数组a中,索引是行的第二个字段的值。 next仅表示awk应移至下一行而不进行进一步处理。

  • a[$2]>0{print a[$2],$1} - 仅对第二个及后续输入文件测试此条件。第二个字段用作从a查找值的索引 - 如果该值大于0(即,在这种情况下该值是字符串)则打印该值,然后是第一个字段当前行的字段。

基本上,第一个文件的每一行都存储在一个数组中,由该行的第二个字段索引。如果在第二个文件中匹配第二个字段,则打印第一个文件中的整行,并附加第二个文件中的第二个字段。

答案 1 :(得分:1)

您可以使用join命令链接文件上的字段。 最简单的使用方法可以是:

 join -j 2

要获取包含第一个文件的第一个和第二个文件的输出,并在第二个文件的第一个字段后面,可以使用-o选项,如下所示:

 join -j 2 -o 1.1 1.2 2.1

要求两个文件中的行都在第二个字段上排序,如果行未正确排序,则可以使用以下bash技巧:

 join -j 2  -o 1.1 1.2 2.1 <(sort -k2 1) <(sort -k2 2)

假设这是两个文件的内容:

 $ cat 1
 FIRST   first
 SECOND  second
 THIRD   third
 FOURTH  fourth
 $ cat 2
 2       second
 1       first
 3       third
 4       fourth

注意:每行的字段分隔符是TAB字符

最终结果:

 $ join -j 2 -o 1.1 1.2 2.1 <(sort 1) <(sort -k2 2)
 FIRST first 1
 FOURTH fourth 4
 SECOND second 2
 THIRD third 3