使用awk

时间:2017-07-22 15:26:54

标签: bash matrix awk data-conversion

我有一个列文件。行数是24的倍数。总行数不是先验的。

我尝试做的是使用awk将单列转换为大小为n x 24的矩阵,其中

n = number_of_rows/24.

我想使用awk,因为我使用管道将tar的输出发送到awk,因为我只需要整个文件的某些列。

myfile.dat包含浮点数:

23.0
20.0
17.0
16.0
16.0
15.0
18.0
20.0
23.0
25.0
27.0
29.0
30.0
31.0
32.0
31.0
30.0
29.0
27.0
25.0
23.0
22.0
20.0
19.0
23.0
22.0

还有更多......

awk '{ 
 for (r = 1; r <= 72; r++) { 
  for (c = 1; c <= 24; c++) {
   a[r, c] =   $1
  }
 }
}
END {
 for (r = 1; r <= 72; r++) {
  for (c = 1; c <= 24; c++) {
   printf a[r, c]
  }
 }
}' myfile.dat

以上所有内容都在一条线上。我使用数字72进行测试,因为我不知道如何获得除以下行之外的总行数:

wc -l myfile.dat

结果是重复每个条目而不是矩阵。

如果我们考虑输入列的每个元素是x [1]到x [n * 24]输出矩阵应该是

x1  x2  x3  x4  ... x24
x25 x26 x27 x28 ... x48
x49 x50 x51 x52 ... x72
...
...                 xn

这有意义吗? 谢谢你的帮助。

3 个答案:

答案 0 :(得分:1)

使用来自stdin的粘贴和数据:

cat file | paste -d " " - - - - - - - - - - - - - - - - - - - - - - - -

输出:

23.0 20.0 17.0 16.0 16.0 15.0 18.0 20.0 23.0 25.0 27.0 29.0 30.0 31.0 32.0 31.0 30.0 29.0 27.0 25.0 23.0 22.0 20.0 19.0
23.0 22.0

答案 1 :(得分:1)

也可以使用pr来指定所需的列数

$ seq 72 | pr -24ats' '
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72


如果pr抱怨page width too narrow,则需要将页面宽度从默认值72增加。公式为(col-1)*len(delimiter) + col,其中col为所需列数

例如:

$ # 99 is minimum width required for 50 columns with single character wide delimiter
$ seq 100 | pr -J -w99 -50ats,
1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50
51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100


由于输出分隔符是空格,也可以使用

< input xargs -d'\n' -n24

-d'\n'以便输入文件中的每一行都被视为单个参数

答案 2 :(得分:0)

这里还可以使用awk的另一种方法。

awk -v divided_by=24 -v end=72 'BEGIN{for(value=1;value<=end;value++){printf("%d %s",value,value%divided_by==0?ORS:"")}}'

或者在这里添加的非单一衬里形式的解决方案。

awk -v divided_by=24 -v end=72 'BEGIN{
        for(value=1;value<=end;value++){
        printf("%d %s",value,value%divided_by==0?ORS:"")
        }}'