用awk拆分多列

时间:2018-01-23 10:00:33

标签: awk

我需要拆分包含多个列的文件,如下所示:

TCONS_00000001       q1:Ovary1.13|Ovary1.13.1|100|32.599877      q2:Ovary2.16|Ovary2.16.1|100|88.36
TCONS_00000002       q1:Ovary1.19|Ovary1.19.1|100|12.876644      q2:Ovary2.15|Ovary2.15.1|100|365.44
TCONS_00000003       q1:Ovary1.19|Ovary1.19.2|0|0.000000         q2:Ovary2.19|Ovary2.19.1|100|64.567

需要输出:

TCONS_00000001       Ovary1.13.1     32.599877      Ovary2.16.1     88.36
TCONS_00000002       Ovary1.19.1     12.876644      Ovary2.15.1     365.44
TCONS_00000003       Ovary1.19.2     0.000000       Ovary2.19.1     64.567

我的尝试:

awk 'BEGIN {OFS=FS="\t"}{split($2,two,"|");split($3,thr,"|");print $1,two[2],two[4],thr[2],thr[4]}' in.file

问题:

我有更多的列可以拆分为2和3,我希望找到一个更短的解决方案,而不是逐个拆分每一列。

2 个答案:

答案 0 :(得分:2)

$ # borrowing simplicity from @Inian's answer ;)
$ awk 'BEGIN{FS=OFS="\t"}
       {for(i=2; i<=NF; i++){split($i,a,/[:|]/); $i=a[3] "\t" a[5]}} 1' ip.txt
TCONS_00000001  Ovary1.13.1 32.599877   Ovary2.16.1 88.36
TCONS_00000002  Ovary1.19.1 12.876644   Ovary2.15.1 365.44
TCONS_00000003  Ovary1.19.2 0.000000    Ovary2.19.1 64.567

$ # previous solution which leaves tab character at end
$ awk -F'\t' '{printf "%s\t",$1;
             for(i=2; i<=NF; i++){split($i,a,/[:|]/); printf "%s\t%s\t",a[3],a[5]};
             print ""}' ip.txt
TCONS_00000001  Ovary1.13.1 32.599877   Ovary2.16.1 88.36   
TCONS_00000002  Ovary1.19.1 12.876644   Ovary2.15.1 365.44  
TCONS_00000003  Ovary1.19.2 0.000000    Ovary2.19.1 64.567  

答案 1 :(得分:2)

虽然Sundeep's answer很棒,但如果您计划对一组记录执行冗余操作,建议使用一个函数并在每条记录上运行它。

我会写一个awk脚本,如下所示

#!/usr/bin/env awk

function split_args(record) {
    n=split(record,split_array,"[:|]")
    return (split_array[3]"\t"split_array[n])
}

BEGIN { FS=OFS="\t" }

{
    for (i=2;i<=NF;i++) {
       $i=split_args($i)
    }
    print
}

并将其作为

调用
awk -f script.awk inputfile

丑陋的命令行版本将是

awk 'function split_args(record) {
         n=split(record,split_array,"[:|]")
         return (split_array[3]"\t"split_array[n])
     } 
     BEGIN { FS=OFS="\t" }    
     {
        for (i=2;i<=NF;i++) {
            $i=split_args($i)
        }
        print
     }
' newfile