Mass grep但基于第一个输入文件排序结果

时间:2015-01-22 13:24:33

标签: unix grep

我有一个文件(称之为fileA),其中包含一个包含重复项的列标识符。它看起来像这样:

GO:0005515
GO:0005737
GO:0005875
GO:0005884
GO:0005200
GO:0005524
GO:0005737
...

我有另一个文件(称为fileB),它包含两列,第一列有标识符,另一列有关联文本。它看起来像这样:

GO:0000001      mitochondrion inheritance
GO:0000002      mitochondrial genome maintenance
GO:0000003      reproduction
GO:0000006      high-affinity zinc uptake transmembrane transporter activity
GO:0000007      low-affinity zinc ion transmembrane transporter activity
GO:0000009      alpha-1,6-mannosyltransferase activity
GO:0000010      trans-hexaprenyltranstransferase activity
GO:0000011      vacuole inheritance
...

我想使用fileA中的标识符来获取与fileB中的标识符和描述匹配的行,并将其输出到另一个fileC中,其顺序与fileA相同,而不是fileB,同时保留重复项。

我尝试过几件不同的事情:

fgrep -f fileA fileB > fileC

这不起作用,因为fileC中的顺序是fileB的顺序,而不是fileA。

for name in `FileA`
do
        grep "$name" FileB >> FileC
done

这应该有效,但输出是:

GO:0005515      protein binding
GO:0005737      cytoplasm
GO:0005737      cytoplasm
GO:0005737      cytoplasm
GO:0005737      cytoplasm
GO:0005737      cytoplasm
GO:0016301      kinase activity
GO:0005525      GTP binding
GO:0005737      cytoplasm
GO:0016021      integral component of membrane
...

它们也不是文件A的顺序(除了前两个)。

有什么想法吗?

2 个答案:

答案 0 :(得分:1)

尝试这个awk单行程序,输出应该遵循fileA的顺序。

awk 'NR==FNR{b[$1]=$0;next}$1 in b{print b[$1]}' fileB fileA

如果fileB中的两列被<tab>分隔,请在-F'\t之后添加awk

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[$1]=$0;next}$1 in b{print b[$1]}' fb fa 
GO:0005515 #1
GO:0005737 #2
GO:0005875 #3
GO:0005884 #4
GO:0005737 #2

你可以看到,输出保留了dup并遵循fileA中的标识符顺序(fa

答案 1 :(得分:1)

经过多次挫折之后,事实证明这个例子中的fileA具有Windows格式(而不是原先认为的fileB)。

虽然fileA是在UNIX系统上生成的,但它是由最初由Windows机器上的程序Blast2GO生成的文件制作的。这就是为什么它没有被发现。

我使用以下命令删除回车:

sed -i 's/\r$//' fileA

...然后是原始帖子中提出的循环和第一个答案中提供的脚本。