【问题标题】:AWK, string match and replaceAWK,字符串匹配和替换
【发布时间】:2016-08-27 15:01:18
【问题描述】:

我有两个文件;第一个看起来像这样,

        SomeFile.CEL    SomeOtherFile.CEL
probe1  111     666
probe2  222     777
probe3  333     888
probe4  444     999
probe5  555     100
probe6  101     102

第二个看起来像这样(注意:重复的probe4,有两个不同的基因名称),

probe1  Gene1
probe2  Gene2
probe3  Gene3
probe4  Gene4A
probe4  Gene4B
probe5  Gene5
probe7  Gene6

我需要的是一个看起来像这样的输出文件,

Gene1 111 666
Gene2 222 777
Gene3 333 888
Gene4A 444 999
Gene4B 444 999
Gene5 555 100

这个理想的输出文件将包含在两个文件之间匹配探针名称的所有基因名称。此外,如果单个探针存在多个名称,我希望为所有可能的基因名称复制表达数据 (444 999)(此示例显示单个探针的 2 个基因名称,但它可能多达 5 或 6 个.) 顺便说一下,所有文件都是制表符分隔的。

我已经搜索过这个论坛和其他论坛,虽然这篇文章很接近,

Replace multiple arguments with gsub

awk print column $3 if $2==a specific value?

awk partly string match (if column partly matches)

Sed pattern to match and replace

Regex match and replace

他们没有回答我的全部问题。

到目前为止,我在这个命令上取得了最大的成功,

awk -F"\t" 'FILENAME=="input1.file"{a[$1]=$1} FILENAME=="input2.file {if(a[$1]){$1="";print $0}}'   input1.file input2.file

但它没有考虑必要的重复。最后,有些文件看起来像 input1,但包含的不仅仅是我描述的两个示例(someFile.CEL 和 someOtherFile.CEL)。可能有多达 50 个样本/CEL 文件。我想我可能必须构建一个脚本,但我想我会先问是否有更简单的方法。

【问题讨论】:

    标签: awk sed


    【解决方案1】:
    $ awk 'NR==FNR{a[$1]=$2 FS $3; next} $1 in a{print $2, a[$1]}' file1 file2
    Gene1 111 666
    Gene2 222 777
    Gene3 333 888
    Gene4A 444 999
    Gene4B 444 999
    Gene5 555 100
    

    【讨论】:

    • 这很好用。除了,如果我在第一个 inputFile 中有超过 2 列的数据,我该怎么办?第一列总是像我展示的那样是一个列表,但在第一列之后可能有多达 50 列数据。
    • 当您提出问题时,请务必包含一个真正代表您的真实数据的示例。没有什么比试图帮助某人然后听到“很好,但我的数据不是真的那样,实际上是这样的......”更糟糕的事情。编辑您的问题以包含一些更具代表性的输入/输出,这样我们就不会剥洋葱了。
    • 看,我的一些数据实际上是这样的,一些更详细(附加列)但格式相同。我只是要求跟进。感谢您的帮助
    • 您是否有任何特殊原因不在您的问题中包含 some is more detailed 数据,以便我们可以针对它测试潜在的解决方案,而不是发布未经测试的内容,然后如果/当它失败时不得不发布重做一遍?
    【解决方案2】:

    joinGNU 命令正是针对这种情况而制定的,它可以与awk 结合使用。

    这个衬里版本适用于第一个文件中的任意数量的列 (FIELDS):

     join SomeFile.CEL SomeOtherFile.CEL | awk '{$1=$NF; $NF=""; print}'
    

    默认情况下,两个文件的第一个 FIELD 用于 JOIN

    这 2 个文件必须按连接字段排序。

    使用 2 个额外的 sort 进行测试,以确保 JOIN 字段已排序:

    $ join <(sort SomeFile.CEL) <(sort SomeOtherFile.CEL) | awk '{$1=$NF; $NF=""; print}'
    Gene1 111 666
    Gene2 222 777
    Gene3 333 888
    Gene4A 444 999
    Gene4B 444 999
    Gene5 555 100
    

    使用另一个包含更多列的第一个文件进行第二次测试:

    $ cat SomeFile_ManyColumns.CEL
    probe1  111     666 666    111 777 888 999
    probe2  222     777 111    666 999 888 777
    probe3  333     888 101    102 999 888 111
    probe4  444     999 876    543 321 678 101
    probe5  555     100 101    543 321 666 999
    probe6  101     102 888    321 543 101 678
    
    $ join <(sort SomeFile_ManyColumns.CEL) <(sort SomeOtherFile.CEL) | awk '{$1=$NF; $NF=""; print}'
    Gene1 111 666 666 111 777 888 999
    Gene2 222 777 111 666 999 888 777
    Gene3 333 888 101 102 999 888 111
    Gene4A 444 999 876 543 321 678 101
    Gene4B 444 999 876 543 321 678 101
    Gene5 555 100 101 543 321 666 999
    

    ----

    对于历史,具有固定列数(字段)的解决方案:

    join -o 2.2,1.2,1.3 SomeFile.CEL SomeOtherFile.CEL
    

    -o 2.2,1.2,1.3指定输出格式:它是一个或多个逗号或空格分隔的规范,每个都是`FILENUM.FIELD'

    测试:

    $ join -o 2.2,1.2,1.3 SomeFile.CEL SomeOtherFile.CEL
    Gene1 111 666
    Gene2 222 777
    Gene3 333 888
    Gene4A 444 999
    Gene4B 444 999
    Gene5 555 100
    

    【讨论】:

    • @GreysonB 顶部的第一个示例是使用第一个文件中的任意数量的列SomeFile.CEL
    • 所以如果我在 input1.file 中有超过三列,我可以使用类似 join -o -a1 2.2,0 input1.file input2.file 的东西吗?
    • @GreysonB 直接使用join &lt;(sort SomeFile.CEL) &lt;(sort SomeOtherFile.CEL) | awk '{$1=$NF; $NF=""; print}'
    • @GreysonB 添加了第二个测试,以说明使用不同的第一个文件具有不同的列数时,相同的一个线性命令会产生良好的输出。
    【解决方案3】:

    有一个不太知名的 unix 工具用于在(排序的)公共列上连接文件,称为 join。您可以像这样在您的情况下使用它:

    join <( sort file2.txt) <(sort file1.txt ) | cut -d\  -f2-
    
    • sorts 对于未排序的文件是必需的
    • cut 需要删除带有探测器名称的第一列
    • 由于排序和切割,awk 可能更快

    【讨论】:

    • 谢谢你,我学到了一些东西!我自己的答案已经更新为这个(对我来说是新的)&lt;(sort file)
    • @Jayjargot 如果你想查找更多关于它的信息,它被称为“进程替换”。
    猜你喜欢
    • 1970-01-01
    • 2015-12-18
    • 2014-01-16
    • 1970-01-01
    • 2014-08-01
    • 2014-08-14
    • 1970-01-01
    • 2013-01-23
    • 2020-08-27
    相关资源
    最近更新 更多