使用awk命令行组合列

时间:2016-07-09 02:40:59

标签: linux bash awk

我想使用awk组合从第4列开始直到列结尾的列。

输入:

1   682333  191.858 191517119   C   A   C   A   A   A   C   A   A   A   A   A
2   1862626 71.9275 56032940    A   C   C   C   A   A   A   C   A   C   A   A
3   11957134    155.78  150230950   B   B   B   B   A   B   A   B   A   B   A   B
4   2516482 51.2692 31496569    B   A   A   A   A   A   A   A   A   A   A   A
5   9378200 51.2798 31572927    A   A   B   B   B   A   A   A   A   A   B   A
6   2071534 52.1573 32824318    A   B   A   B   A   B   A   B   B   B   A   B
7   2074633 33.068  19035920    A   A   B   A   A   A   B   A   B   A   B   A
8   7856856 121.811 117540910   A   A   A   A   A   A   A   A   B   A   B   A
9   3741206 2.18574 2169864 A   A   A   A   A   A   A   A   A   A   A   A
10  4411364 12.5959 24191374    C   C   A   C   A   C   C   C   A   C   A   C

输出:

1   682333  191.858 191517119   CA      CA      AA      CA      AA      AA
2   1862626 71.9275 56032940    AC      CC      AA      AC      AC      AA
3   11957134    155.78  150230950   BB      BB      AB      AB      AB      AB
4   2516482 51.2692 31496569    BA      AA      AA      AA      AA      AA
5   9378200 51.2798 31572927    AA      BB      BA      AA      AA      BA
6   2071534 52.1573 32824318    AB      AB      AB      AB      BB      AB
7   2074633 33.068  19035920    AA      BA      AA      BA      BA      BA
8   7856856 121.811 117540910   AA      AA      AA      AA      BA      BA
9   3741206 2.18574 2169864 AA      AA      AA      AA      AA      AA
10  4411364 12.5959 24191374    CC      AC      AC      CC      AC      AC

顺便说一下,如果有一个awk命令教程的好网站,请在这里推荐。

3 个答案:

答案 0 :(得分:3)

在我的书中,' one-liner'是一个滥用的术语,除非代码适合大约80个字符以下的单行。我认为当使用多行语句对多个语句进行格式化时,awk代码更易于理解。因此,我想出了这个略有不同版本的代码。线路上有奇数个字段的情况并不需要特殊处理。访问$(NF+1)将给出一个空字符串(或零号)。

awk '{  printf("%s\t%s\t%s\t%s", $1, $2, $3, $4)
        for (i = 5; i <= NF; i += 2)
            printf("\t%s%s", $i, $(i+1))
        print ""
     }' data

根据问题中的数据布局判断,在原始数据中使用了制表符分隔符,但是演示文稿的tabstops设置为4个空格。因此,代码使用制表符作为分隔符。我在包含以下内容的示例数据中添加了一行:

11  1111111 22.2222 33333333    D   D   W   W   X   X   Y   Y   Z   Z   =

我从中获得的输出加上问题中的数据在将tabstops设置为4格式化之后看起来像这样:

1   682333  191.858 191517119   CA  CA  AA  CA  AA  AA
2   1862626 71.9275 56032940    AC  CC  AA  AC  AC  AA
3   11957134    155.78  150230950   BB  BB  AB  AB  AB  AB
4   2516482 51.2692 31496569    BA  AA  AA  AA  AA  AA
5   9378200 51.2798 31572927    AA  BB  BA  AA  AA  BA
6   2071534 52.1573 32824318    AB  AB  AB  AB  BB  AB
7   2074633 33.068  19035920    AA  BA  AA  BA  BA  BA
8   7856856 121.811 117540910   AA  AA  AA  AA  BA  BA
9   3741206 2.18574 2169864 AA  AA  AA  AA  AA  AA
10  4411364 12.5959 24191374    CC  AC  AC  CC  AC  AC
11  1111111 22.2222 33333333    DD  WW  XX  YY  ZZ  =

答案 1 :(得分:2)

与@sps答案非常相似,但没有if和using标签

awk '{ printf $1; for (i=2; i<=4; i++) {printf "\t%s",$i}; for (i=5; i<=NF; i+=2) {  printf "\t%s%s",$i,$(i+1);} printf "\n"; }' filename

答案 2 :(得分:0)

这可能看起来很乱,但应该有效。

awk '{for(i=1; i<=4; i++) {printf "%s  ",$i;} for(i=5; i<=NF; i++) {printf "%s", $i; if(i<NF){i++; printf "%s",$i;} printf "\t"} printf "\n"; }' filename 

这里我们打印前4列 - 它们之间有两个空格(因此它们之间的任何原始格式都会改变) - 然后通过组合二对一打印剩余的列以及它们之间的标签(您可以将制表符更改为一些空格) )

相关问题