将文本文件转换为列

gre*_*eta 6 unix linux awk

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

1  
2  
3  
......  
30 
Run Code Online (Sandbox Code Playgroud)

新输出应该是我有nm行的新列.坚持我的例子有30个字段输入和n = 3,m = 10,我需要一个这样的输出文件(分隔符无关紧要,可能是空白,选项卡等):

1   11  21  
2   12  22  
... ... ...
10  20  30 
Run Code Online (Sandbox Code Playgroud)

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

Chr*_*our 10

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

pr -ts" " --columns 3 file
Run Code Online (Sandbox Code Playgroud)


mpl*_*ork 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
Run Code Online (Sandbox Code Playgroud)

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

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

希望这能让你开始。

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

{ split($0,data); }
Run Code Online (Sandbox Code Playgroud)

{ data[++i] = $1; }
Run Code Online (Sandbox Code Playgroud)

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

编辑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
Run Code Online (Sandbox Code Playgroud)

但是,由于您只想重新格式化数据,因此可以立即执行此操作。将两个解决方案结合起来,在命令行上删除data并传递mand :n

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
Run Code Online (Sandbox Code Playgroud)