【问题标题】:How to transfer the data of columns to rows (with awk)?如何将列的数据传输到行(使用awk)?
【发布时间】:2012-03-21 01:00:02
【问题描述】:

我有一个这样的文件:

n A B C D 
1 01 02 01 01
2 02 02 01 01

我想逐行传输列,所以输出应该是这样的:

n 1 2
A 01 02
B 02 02
C 01 01 
D 01 01

我已经写了这个命令:

awk '{ for (i=1;i<=NF;i++ ) printf $i " " }' file.txt > out-file.txt

问题是这个命令把所有东西都放在了一行!所以输出是这样的:

n 1 2 A 01 02 B 02 02 C 01 01 D 01 01

【问题讨论】:

标签: linux awk rows


【解决方案1】:

这可能有效:

awk '{
       for (f = 1; f <= NF; f++) { a[NR, f] = $f } 
     }
     NF > nf { nf = NF }
     END {
       for (f = 1; f <= nf; f++) {
           for (r = 1; r <= NR; r++) {
               printf a[r, f] (r==NR ? RS : FS)
           }
       }
    }' YOURINPUT

in action @ Ideone

【讨论】:

    【解决方案2】:

    将此脚本另存为 transpose.awk 和 chmod u+x transpose.awk。是对Tim Sherwood'stranspose的修改。

    #!/usr/bin/gawk -f
    
    BEGIN {
        max_x =0;
        max_y =0;
    }
    
    {
        max_y++;
        for( i=1; i<=NF; i++ )
        {
            if (i>max_x) max_x=i;
            A[i,max_y] = $i;
        }
    }
    
    END {
        for ( x=1; x<=max_x; x++ )
        {
            for ( y=1; y<=max_y; y++ )
            {
                if ( (x,y) in A ) printf "%s",A[x,y];
                if ( y!=max_y ) printf " ";
            }
            printf "\n";
        }
    }
    

    例子:

    $ ./transpose.awk example
    n 1 2
    A 01 02
    B 02 02
    C 01 01
    D 01 01
    

    【讨论】:

    • 感谢您的链接。它充满了很棒的脚本!
    【解决方案3】:

    这是一个不同的解决方案,它只涉及最后一个 for 循环:

    { for (i=1; i<=NF; i++) col[i] = col[i] " " $i }
    END { 
        for (i=1; i<=NF; i++) { 
            sub(/^ /, "", col[i]); 
            print col[i] 
        } 
    }
    

    讨论

    • 此解决方案使用一维数组col,用于存储整列的值。 col[1] 是第一列。
    • 对于每一行,我们将列附加到 col[i]。因为我们盲目追加,所以 col[i] 值将包含前导空格。
    • 最后,sub() 函数在打印出列(现在是一行)之前删除前导空格

    【讨论】:

      【解决方案4】:

      好吧,不用 awk 我们可以用 cat 做到这一点:

      for x in `cat filename`
      do
      echo $x
      done
      

      使用此脚本,结果将出现在 cols 中。

      【讨论】:

        【解决方案5】:

        使用rs会更方便:

        $ cat /tmp/a
        n A B C D
        1 01 02 01 01
        2 02 02 01 01
        $ rs -c' ' -C' ' -T</tmp/a
        n 1 2
        A 01 02
        B 02 02
        C 01 01
        D 01 01
        

        -c 更改输入列分隔符,-C 更改输出列分隔符,-T 转置行和列。

        【讨论】:

        • 好极了~?????
        猜你喜欢
        • 2022-11-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-11-05
        • 2012-04-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多