【问题标题】:Put every N rows of input into a new column将每 N 行输入放入一个新列
【发布时间】:2013-01-09 06:33:25
【问题描述】:

在 bash 中,给定输入

1
2
3
4
5
6
7
8
...

N例如5,我想要输出

1  6  11
2  7  12
3  8  ...
4  9
5  10 

我该怎么做?

【问题讨论】:

    标签: linux bash shell unix awk


    【解决方案1】:

    这是我使用awk 的方法:

    awk -v n=5 '{ c++ } c>n { c=1 } { a[c] = (a[c] ? a[c] FS : "") $0 } END { for (i=1;i<=n;i++) print a[i] }'
    

    一些简单的测试:

    seq 21 | awk -v n=5 '{ c++ } c>n { c=1 } { a[c] = (a[c] ? a[c] FS : "") $0 } END { for (i=1;i<=n;i++) print a[i] | "column -t" }'
    

    结果:

    1  6   11  16  21
    2  7   12  17
    3  8   13  18
    4  9   14  19
    5  10  15  20
    

    还有一个:

    seq 40 | awk -v n=6 '{ c++ } c>n { c=1 } { a[c] = (a[c] ? a[c] FS : "") $0 } END { for (i=1;i<=n;i++) print a[i] | "column -t" }'
    

    结果:

    1  7   13  19  25  31  37
    2  8   14  20  26  32  38
    3  9   15  21  27  33  39
    4  10  16  22  28  34  40
    5  11  17  23  29  35
    6  12  18  24  30  36
    

    【讨论】:

      【解决方案2】:

      使用一个鲜为人知的 gem pr:

      $ seq 20 | pr -ts' ' --column 4
      1 6 11 16
      2 7 12 17
      3 8 13 18
      4 9 14 19
      5 10 15 20
      

      【讨论】:

      • 如果它能够完成工作,它只是一个宝石。例如,您应该使用seq 21 进行测试。如您所见,您需要进行一些后期处理才能获得所需的输出。否则上面的命令会在没有修改的情况下失败。
      • @user19340357:我不相信它会达到预期的效果。无论如何,在研究命令的工作原理时,您应该首先查看该特定命令的手册页。在这种情况下,键入:man pr 以查看 pr 的手册页。鉴于在这种情况下只有三个选项传递给 pr,是否有一个没有很好记录的特定标志需要更多解释?
      【解决方案3】:

      将以下脚本中的 5 替换为您的号码。

      seq 20|xargs -n5| awk '{for (i=1;i<=NF;i++) a[i,NR]=$i; }END{
          for(i=1;i<=NF;i++) {for(j=1;j<=NR;j++)printf a[i,j]" "; print "" }}' 
      

      输出:

      1 6 11 16 
      2 7 12 17 
      3 8 13 18 
      4 9 14 19 
      5 10 15 20
      

      注意上面的seq 20 只是用于生成用于测试的数字序列。你在实际工作中不需要它。

      编辑

      正如 sudo_O 所指出的,我添加了一个纯 awk 解决方案:

       awk -vn=5 '{a[NR]=$0}END{ x=1; while (x<=n){ for(i=x;i<=length(a);i+=n) printf a[i]" "; print ""; x++; } }' file
      

      测试

      kent$  seq 20| awk -vn=5 '{a[NR]=$0}END{ x=1; while (x<=n){ for(i=x;i<=length(a);i+=n) printf a[i]" "; print ""; x++; } }'     
      1 6 11 16 
      2 7 12 17 
      3 8 13 18 
      4 9 14 19 
      5 10 15 20 
      
      kent$  seq 12| awk -vn=5 '{a[NR]=$0}END{ x=1; while (x<=n){ for(i=x;i<=length(a);i+=n) printf a[i]" "; print ""; x++; } }'     
      1 6 11 
      2 7 12 
      3 8 
      4 9 
      5 10 
      

      【讨论】:

      • @sudo_O thx 指出来,我没有测试那个案例,现在添加了一个纯 awk 单行。
      • 你可以用{1..12}代替seq 12
      • @Kent 取决于你的技能 :)
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-06-01
      • 2020-02-21
      • 2021-08-31
      • 2016-07-16
      • 2010-10-06
      • 1970-01-01
      相关资源
      最近更新 更多