批量 grep 但根据第一个输入文件对结果进行排序
Mass grep but sorting results based on first input file
我有一个文件(称为 fileA),其中包含重复的单列标识符。看起来像这样:
GO:0005515
GO:0005737
GO:0005875
GO:0005884
GO:0005200
GO:0005524
GO:0005737
...
我有另一个包含两列的文件(称之为 fileB),第一列有标识符,另一列有关联的文本。看起来像这样:
GO:0000001 线粒体遗传
GO:0000002 线粒体基因组维护
GO:0000003 复制
GO:0000006 高亲和力锌摄取跨膜转运蛋白 activity
GO:0000007 低亲和力锌离子跨膜转运蛋白 activity
GO:0000009 α-1,6-甘露糖基转移酶 activity
GO:0000010 反式六戊二烯转移酶 activity
GO:0000011 液泡遗传
...
我想用 fileA 中的标识符进行 grep,以从 fileB 中获取具有标识符和描述的匹配行,并将其输出到另一个 fileC 中,其顺序与 fileA 相同,而不是 fileB,同时保留重复项。
我尝试了几种不同的方法:
fgrep -f fileA fileB > fileC
这不起作用,因为文件 C 中的顺序是文件 B 的顺序,而不是文件 A。
`FileA` 中的名称
做
grep "$name" 文件 B >> 文件 C
完成
这应该可以,但输出是:
GO:0005515 蛋白质结合
GO:0005737 细胞质
GO:0005737 细胞质
GO:0005737 细胞质
GO:0005737 细胞质
GO:0005737 细胞质
GO:0016301 激酶 activity
GO:0005525 GTP 绑定
GO:0005737 细胞质
GO:0016021 膜的组成部分
...
它们也不符合文件A的顺序(除了前两个)。
有什么想法吗?
试试这个 awk 单行代码,输出应该按照文件 A 的顺序。
awk 'NR==FNR{b[]=[=10=];next} in b{print b[]}' fileB fileA
如果您的 fileB
中的两列被 <tab>
分隔,请在 awk
之后添加 -F'\t
因此:
awk -F'\t' 'NR==FNR......`
添加测试
kent$ head fa fb
==> fa <==
GO:0005515
GO:0005737
GO:0005875
GO:0005884
GO:0005200
GO:0005524
GO:0005737
==> fb <==
GO:0005875 #3
fooo
GO:0005515 #1
fooo
GO:0005737 #2
fooo
GO:0005884 #4
fooo
kent$ awk 'NR==FNR{b[]=[=12=];next} in b{print b[]}' fb fa
GO:0005515 #1
GO:0005737 #2
GO:0005875 #3
GO:0005884 #4
GO:0005737 #2
你可以看到,输出保留了重复项并遵循文件 A (fa
)
中的标识符顺序
经过多次挫折后,事实证明本例中的文件 A 具有 Windows 格式(不是最初认为的文件 B)。
尽管文件 A 是在 UNIX 系统上生成的,但它是由最初由程序 Blast2GO 在 Windows 机器上生成的文件生成的。这就是为什么它没有早点被发现的原因。
我使用以下命令删除回车符 returns:
sed -i 's/\r$//' fileA
...然后是原始 post 中建议的循环和第一个答案中提供的脚本。
我有一个文件(称为 fileA),其中包含重复的单列标识符。看起来像这样:
GO:0005515 GO:0005737 GO:0005875 GO:0005884 GO:0005200 GO:0005524 GO:0005737 ...
我有另一个包含两列的文件(称之为 fileB),第一列有标识符,另一列有关联的文本。看起来像这样:
GO:0000001 线粒体遗传 GO:0000002 线粒体基因组维护 GO:0000003 复制 GO:0000006 高亲和力锌摄取跨膜转运蛋白 activity GO:0000007 低亲和力锌离子跨膜转运蛋白 activity GO:0000009 α-1,6-甘露糖基转移酶 activity GO:0000010 反式六戊二烯转移酶 activity GO:0000011 液泡遗传 ...
我想用 fileA 中的标识符进行 grep,以从 fileB 中获取具有标识符和描述的匹配行,并将其输出到另一个 fileC 中,其顺序与 fileA 相同,而不是 fileB,同时保留重复项。
我尝试了几种不同的方法:
fgrep -f fileA fileB > fileC
这不起作用,因为文件 C 中的顺序是文件 B 的顺序,而不是文件 A。
`FileA` 中的名称 做 grep "$name" 文件 B >> 文件 C 完成
这应该可以,但输出是:
GO:0005515 蛋白质结合 GO:0005737 细胞质 GO:0005737 细胞质 GO:0005737 细胞质 GO:0005737 细胞质 GO:0005737 细胞质 GO:0016301 激酶 activity GO:0005525 GTP 绑定 GO:0005737 细胞质 GO:0016021 膜的组成部分 ...
它们也不符合文件A的顺序(除了前两个)。
有什么想法吗?
试试这个 awk 单行代码,输出应该按照文件 A 的顺序。
awk 'NR==FNR{b[]=[=10=];next} in b{print b[]}' fileB fileA
如果您的 fileB
中的两列被 <tab>
分隔,请在 awk
之后添加 -F'\t
因此:
awk -F'\t' 'NR==FNR......`
添加测试
kent$ head fa fb
==> fa <==
GO:0005515
GO:0005737
GO:0005875
GO:0005884
GO:0005200
GO:0005524
GO:0005737
==> fb <==
GO:0005875 #3
fooo
GO:0005515 #1
fooo
GO:0005737 #2
fooo
GO:0005884 #4
fooo
kent$ awk 'NR==FNR{b[]=[=12=];next} in b{print b[]}' fb fa
GO:0005515 #1
GO:0005737 #2
GO:0005875 #3
GO:0005884 #4
GO:0005737 #2
你可以看到,输出保留了重复项并遵循文件 A (fa
)
经过多次挫折后,事实证明本例中的文件 A 具有 Windows 格式(不是最初认为的文件 B)。
尽管文件 A 是在 UNIX 系统上生成的,但它是由最初由程序 Blast2GO 在 Windows 机器上生成的文件生成的。这就是为什么它没有早点被发现的原因。
我使用以下命令删除回车符 returns:
sed -i 's/\r$//' fileA
...然后是原始 post 中建议的循环和第一个答案中提供的脚本。