将文本文件转换为列

时间:2013-03-28 16:51:35

标签: linux unix awk

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

1  
2  
3  
......  
30 

新输出应该是 n m 行的新列。坚持我的例子有30个字段输入和 n = 3, m = 10,我需要一个像这样的输出文件(分隔符并不重要,可能是一个空白,标签等。):

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

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

4 个答案:

答案 0 :(得分:10)

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

pr -ts" " --columns 3 file

答案 1 :(得分: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。它将您的输入拆分为空白并创建数组dataEND块在处理文件后运行,只需按索引访问data。注意数组索引从0开始计算。

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

希望这能让你开始。

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

{ split($0,data); }

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

考虑输入在不同的行上。实际上,这将为您提供首先将其读入二维数组的选项。

编辑2

读取二维数组 假设mn预先知道并且不以某种方式在输入中编码,则读取为二维数组:

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

答案 2 :(得分:2)

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

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

这是通过一次读取记录,每行连接每行与前面的行。当连接n行时,它会在单个新行上打印连接结果。重复此操作直到输入中没有剩余行。

答案 3 :(得分:1)

您可以使用以下命令

paste - - - < input.txt

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

paste - - - -d' ' < input.txt