从xyz到带有awk的矩阵

时间:2011-10-26 16:55:18

标签: matrix awk

我有一个问题,我设法通过解决方法来解决,所以我在这里希望向您学习更优雅的解决方案; - )

我必须解析一个程序的输出:它写一个三列的文件x y z像这样

1 1 11  
1 2 12  
1 3 13  
1 4 14  
2 1 21  
2 2 22  
2 3 23  
2 4 24  
3 1 31  
3 2 32  
3 3 33  
3 4 34  
4 1 41  
4 2 42  
4 3 43  
4 4 44  

在像这样的矩阵中

11 12 13 14  
21 22 23 24  
31 32 33 34  
41 42 43 44  

我用这样的两行bash脚本解决了

dim_matrix=$(awk 'END{print sqrt(NR)}' file_xyz) #since I know that the matrix has to be squared and there are no blank lines in the file_xyz  
awk '{printf("%s%s",$3, !(NR%'${dim_matrix}'==0) ? OFS :ORS ) }' file_xyz  

请您建议我使用awk执行相同操作的方法吗?

3 个答案:

答案 0 :(得分:1)

我不完全确定你尝试做什么,试试这个:

awk 'NR%4==0{print s " " $NF;s="";next}{s=s?s " " $NF:$NF}' file1

答案 1 :(得分:1)

awk没有真正的多维数组,但你可以使用正确构造的字符串伪造它:

awk '
  {mx[$1 "," $2] = $3}
  END {
    size=sqrt(NR)
    for (x=1; x<=size; x++) {
      for (y=1; y<=size; y++)
          printf("%s ",mx[x "," y])
      print ""
    }
  }
' filename

您可以通过一次awk通话和对wc

的调用来完成您的示例
awk -v "nlines=$(wc -l < filename)" '
  BEGIN {size = sqrt(nlines)}
  {printf("%s%s", $3, (NR % size == 0 ? ORS : OFS))
}' filename

答案 2 :(得分:1)

“不那么”可读的版本:

awk '($0=$NF x)&&ORS=NR%4?FS:RS' infile

根据OP的请求添加的参数:

awk '
  ($0 = $NF x) && ORS = NR % n ? FS : RS
  ' n="$1" infile

在上面的脚本中,我使用$ 1,但您可以使用任何 shell 变量。

解释如下:

$0 = $NF - 设置$ 0(整个当前输入记录) 到最后一个字段的当前值($ NF)。

ORS = NR % n ? FS : RS - 使用三元运算符:

expression ? return_this_if_true : return_this_otherwise

将OutputRecordSeparator设置为:

  • 当NR%n评估为真时(即返回值不等于0)  将ORS设置为FS的当前值(FieldSeparator - 运行空白区域  默认情况下的字符)

  • 否则将其设置为RS(默认为换行符)

x(一个整数变量,因此在串联时使用NULL字符串) 需要正确处理输出 当最后一个字段为0(或空字符串)时。 这是因为awk中的assignement声明 实际上在这种情况下返回指定的值, 如果$ NF为0,其余的&amp;&amp;布尔语句 将被忽略。