我一直在论坛中搜索我的问题的解决方案,但不幸的是我没有成功。我在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
非常感谢您的时间和帮助。
最佳。
答案 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