9

假设我有科学数据,所有数字都排列在单列中,但表示n(宽度)乘m(高度)的强度矩阵。输入文件的列共有n * m行。输入示例可能如下所示:

1  
2  
3  
......  
30 

新的输出应该是这样,我有m行的n 个新列。坚持我的示例,输入 30 个字段,n = 3,m = 10,我需要这样的输出文件(分隔符无关紧要,可以是空白、制表符等):

1   11  21  
2   12  22  
... ... ...
10  20  30 

我在 Windows 下使用 gawk。请注意,没有特殊FS的,更真实的例子是 60 * 60 或更大。

4

4 回答 4

15

如果您不限于awk但拥有 GNU core-utils (cygwin, native, ..),那么最简单的解决方案是使用pr

pr -ts" " --columns 3 file
于 2013-03-29T14:01:43.590 回答
3

我相信这会做到:

awk '
  { split($0,data); }
  END {
     m = 10;
     n = 3;
     for( i = 1; i<=m; i++ ) {
        for( j = 0; j<n; j++ ) {
            printf "%s ", data[j*m + i] # output data plus space in one line
        }
        # here you might want to start a new line though you did not ask for it:
        printf "\n"; 
     }
  }' inputfile

我可能有错误的索引计数,但我相信你能弄清楚。诀窍是split在第一行。它将您的输入拆分为空格并创建一个数组data。该END块在处理您的文件后运行,仅data按索引访问。注意数组索引从 0 开始计数。

假设所有数据都在一行中。你的问题在这方面不是很清楚。如果它在多行上,则必须以不同的方式将其读入数组。

希望这能让你开始。

编辑 我注意到你在我回答的时候改变了你的问题。所以改变

{ split($0,data); }

{ data[++i] = $1; }

考虑输入在不同的行上。实际上,这将使您首先可以选择将其读入二维数组。

编辑 2

读取二维数组 要读取为二维数组,假设m并且n事先已知并且未以某种方式在输入中编码:

awk '
  BEGIN {
     m = 10;
     n = 3;
  }
  { 
     for( i = 0; i<m; i++ ) {
        for( j = 0; j<n; j++ ) {
            data[i,j] = $0;
        }
     }
     # do something with data
  }' inputfile

但是,由于您只想重新格式化您的数据,您可以立即进行。结合两种解决方案摆脱并在命令行上data传递:mn

awk -v m=10 -v n=3'
  { 
     for( i = 0; i<m; i++ ) {
        for( j = 0; j<n; j++ ) {
            printf "%s ", $0     # output data plus space in one line
        }
        printf "\n";
     }
  }' inputfile
于 2013-03-28T17:27:24.897 回答
2

这是一个相当简单的解决方案(在示例中我设置n为 3;为 插入适当的值n):

awk -v n=3 '{ row = row $1 " "; if (NR % n == 0) { print row; row = "" } }' FILE

这通过一次读取一行将每一行与前面的行连接起来来实现。连接行后n,它将连接的结果打印在一个新行上。重复此过程,直到输入中没有更多行。

于 2013-04-05T11:06:36.687 回答
2

您可以使用以下命令

paste - - - < input.txt

默认情况下,分隔符是 TAB,要更改分隔符,请使用以下命令

paste - - - -d' ' < input.txt
于 2016-03-07T06:49:56.457 回答