如何将多列拆分为几列?

时间:2019-04-14 21:07:04

标签: bash awk

我有以下数据:

CustomersThatStartWith

我想这样重新排列:

 X  Y  Z    X  Y  Z   X  Y  Z   
 1  2  3    4  5  6   7  8  9

 X  Y  Z    X  Y  Z   X  Y  Z    
10 11 12   13 14 15  16 17 18

使用 X Y Z 1 2 3 X Y Z 4 5 6 X Y Z 7 8 9 X Y Z 10 11 12 X Y Z 13 14 15 X Y Z 16 17 18 ,我可以打印一组列,但不能如上所述以所需的方式排列。

任何帮助将不胜感激。

2 个答案:

答案 0 :(得分:1)

尝试:

awk '!(NR%2){for (i=1;i<=NF-2;i=i+3){print a[i], a[i+1], a[i+2]; print $i, $(i+1), $(i+2)}} {split($0,a)}' file

示例

考虑此测试文件:

$ cat file
 X  Y  Z    X  Y  Z   X  Y  Z
 1  2  3    4  5  6   7  8  9
 X  Y  Z    X  Y  Z   X  Y  Z
10 11 12   13 14 15  16 17 18

现在运行我们的命令:

$ awk '!(NR%2){for (i=1;i<=NF-2;i=i+3){print a[i], a[i+1], a[i+2]; print $i, $(i+1), $(i+2)}} {split($0,a)}' file
X Y Z
1 2 3
X Y Z
4 5 6
X Y Z
7 8 9
X Y Z
10 11 12
X Y Z
13 14 15
X Y Z
16 17 18

工作原理

  • !(NR%2){for (i=1;i<=NF-2;i=i+3){print a[i], a[i+1], a[i+2]; print $i, $(i+1), $(i+2)}}

    在偶数行上,打印前一行的三个值(存储在数组a中),然后从当前行打印三个值,并重复直到所有值都打印出来。

  • split($0,a)

    将当前行中的值保存在数组a中。

答案 1 :(得分:0)

$ cat tst.awk
# numCols in how many fields are required in output, can be passed as -v numCols=<number>
BEGIN { OFS="\t"; numCols=(numCols ? numCols : 3) }
!NF { prt(); numRows=0; next }
{
    ++numRows
    numGrps = 0
    colNr = 0
    for (i=1; i<=NF; i++) {
        colNr = ( (i - 1) % numCols ) + 1
        numGrps += ( colNr == 1 ? 1 : 0 )
        val[numGrps,numRows,colNr] = $i
    }
}
END { prt() }

function prt(   rowNr, grpNr, colNr) {
    for (grpNr=1; grpNr<=numGrps; grpNr++) {
        for (rowNr=1; rowNr<=numRows; rowNr++) {
            for (colNr=1; colNr<=numCols; colNr++) {
                printf "%s%s", val[grpNr,rowNr,colNr], (colNr<numCols ? OFS : ORS)
            }
        }
        print ""
    }
}

$ awk -f tst.awk file
X       Y       Z
1       2       3

X       Y       Z
4       5       6

X       Y       Z
7       8       9

X       Y       Z
10      11      12

X       Y       Z
13      14      15

X       Y       Z
16      17      18