![用替代单词替换制表符分隔文件中的多个单词](https://linux22.com/image/111582/%E7%94%A8%E6%9B%BF%E4%BB%A3%E5%8D%95%E8%AF%8D%E6%9B%BF%E6%8D%A2%E5%88%B6%E8%A1%A8%E7%AC%A6%E5%88%86%E9%9A%94%E6%96%87%E4%BB%B6%E4%B8%AD%E7%9A%84%E5%A4%9A%E4%B8%AA%E5%8D%95%E8%AF%8D.png)
我有一个制表符分隔的文件,其中包含指示生物体的代码(例如 ctc、nmg、nml)(File_1):
522 ctc:CTC00972 - 506 3.20E-138
522 nmg:Nmag_3027 - 561 4.70E-73
522 nml:Namu_3564 - 566 1.80E-146
我还有一个制表符分隔的文件,它将代码链接到生物体名称 (File_2):
ctc Clostridium_tetani_E88
nla Neisseria_lactamica
nmg Natrialba_magadii
如何用 File_2 中的生物体名称替换 File_1 中的代码?
期望的输出:
522 Clostridium_tetani_E88:CTC00972 - 506 3.20E-138
522 Natrialba_magadii:Nmag_3027 - 561 4.70E-73
522 Neisseria_lactamica:Namu_3564 - 566 1.80E-146
请记住,完整数据集中有数千个这样的代码,并且 File_1 和 File_2 中的生物体顺序不同。
答案1
它实际上只是“从一个文件构建查找表;在处理另一个文件时使用它”的一种变体,其缺点是查找键需要从第二个字段中分离出来。awk
例如,您可以这样做:
awk '
BEGIN{OFS=FS="\t"}
NR==FNR {
a[$1]=$2; next
}
{
split($2,b,":");
if (b[1] in a) $2 = a[b[1]]":"b[2]
} 1' File_2 File_1
答案2
这应该可以完成以下工作sed
:
sed '/^[a-z]*[[:cntrl:]].*/{s/[[:cntrl:]]/###/;H;d;}
G
s/\([a-z]*\)\(:.*\n\)\1###\([^[:cntrl:]]*\)/\3\2/
P
d' file_2 file_1
这是一个采用这个通用解决方案。请参阅此处了解其工作原理的说明。
答案3
awk方法:
awk 'NR==FNR{a[$1]=$2;next}$2 in a{$2=a[$2]":"$3;$3=""}1' File_2 FS="[ |:]" File_1
输出:
522 Clostridium_tetani_E88:CTC00972 - 506 3.20E-138
522 Natrialba_magadii:Nmag_3027 - 561 4.70E-73
522 nml:Namu_3564 - 566 1.80E-146
请注意,nml
和nla
代码在 2 个输入文件之间不匹配