【问题标题】:Mass grep but sorting results based on first input fileMass grep,但根据第一个输入文件对结果进行排序
【发布时间】:2015-01-22 13:24:33
【问题描述】:

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

转到:0005515
去:0005737
去:0005875
去:0005884
去:0005200
去:0005524
去:0005737
...

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

GO:0000001 线粒体继承
GO:0000002 线粒体基因组维护
GO:0000003 复制
GO:0000006 高亲和力锌摄取跨膜转运蛋白活性
GO:0000007 低亲和力锌离子跨膜转运蛋白活性
GO:0000009 α-1,6-甘露糖基转移酶活性
GO:0000010 反式六戊二烯转移酶活性
GO:0000011 液泡继承
...

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

我尝试了几种不同的方法:

fgrep -f fileA fileB > fileC

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

对于 `FileA` 中的名称
做
        grep "$name" FileB >> FileC
完成

这应该可以,但输出是:

GO:0005515 蛋白结合
GO:0005737 细胞质
GO:0005737 细胞质
GO:0005737 细胞质
GO:0005737 细胞质
GO:0005737 细胞质
GO:0016301 激酶活性
GO:0005525 GTP 绑定
GO:0005737 细胞质
GO:0016021 膜的整体组件
...

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

有什么想法吗?

【问题讨论】:

    标签: unix grep


    【解决方案1】:

    试试这个awk单行,输出应该按照fileA的顺序。

    awk 'NR==FNR{b[$1]=$0;next}$1 in b{print b[$1]}' 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[$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
    

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

    【讨论】:

    • 不幸的是,这两个似乎都按照在原始帖子中使用 bash 脚本观察到的顺序返回它,而不是按照文件 A 的顺序返回,并且只返回标识符,而不是标识符 + 描述。
    • @EKarl 我添加了一个测试,描述很简单,如 indexNo。显示顺序。检查你是否得到相同的输出。
    • 我得到了你的测试用例的结果,但不是我的用例。我的一个文件,一个同时包含标识符和描述的文件,是在一台 Windows 机器上准备的,而 UNIX 处理是在一台 UNIX 机器上完成的。这可能是问题的一部分吗?
    • 有一些像dos2unix这样的工具可以将dos/win格式转换为unix,例如换行符......你可以试试@EKarl
    【解决方案2】:

    经过一番挫折后,事实证明,这个示例中的 fileA 具有 Windows 格式(而不是最初认为的 fileB)。

    虽然 fileA 是在 UNIX 系统上生成的,但它是由最初由 Windows 机器上的 Blast2GO 程序生成的文件生成的。这就是为什么它没有早点被抓到的原因。

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

    sed -i 's/\r$//' 文件A

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

    【讨论】:

      猜你喜欢
      • 2021-03-30
      • 1970-01-01
      • 1970-01-01
      • 2014-12-02
      • 2018-12-15
      • 2019-01-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多