使用 awk 从 xyz 到矩阵
我有一个问题,我设法通过变通办法解决,所以我在这里希望向您学习更优雅的解决方案;-)
我必须解析程序的输出:它
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
在一个文件中 写入一个三列 xyz 的文件,如下所示像这样的矩阵
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执行相同操作的方法吗?
I have a problem that I managed to solve with a work around so I am here hoping to learn from you more elegant solutions ;-)
I have to parse the output of a program: it writes a file of three columns x y z like this
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
in a matrix like this
11 12 13 14
21 22 23 24
31 32 33 34
41 42 43 44
I solved with a two line bash script like this
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
Can you please suggest me a way to perform the same only with awk?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
awk 不执行真正的多维数组,但您可以使用正确构造的字符串来伪造它:
您可以通过单个 awk 调用和对
wc
的调用来完成您的示例awk does not do real multidimensional arrays, but you can fake it with a properly constructed string:
You can accomplish your example with a single awk call and a call to
wc
一个“不太”可读的版本:
根据OP的请求添加参数:
在上面的脚本中我使用$1,但您可以使用任何shell变量。
解释如下:
$0 = $NF
- 设置$0(整个当前输入记录)到最后一个字段的当前值 ($NF)。
ORS = NR % n ? FS : RS - 使用三元运算符:
表达式? return_this_if_true : return_this_otherwise
,将 OutputRecordSeparator 设置为:
当 NR % n 计算结果为 true 时(即返回值不同于 0)
将 ORS 设置为 FS 的当前值(FieldSeparator - 空格运行
默认字符)
否则将其设置为 RS(默认为换行符)
x(一个统一变量,因此在连接中使用时为 NULL 字符串) )
为了正确处理输出需要
当最后一个字段为 0(或空字符串)时。
这是因为awk中的赋值语句
实际上在这种情况下返回分配的值,
如果 $NF 为 0,则 && 的其余部分布尔语句
将被忽略。
A "not so" readable version:
Parameters added as per OP's request:
In the script above I'm using $1, but you can use any shell variable.
The explanation follows:
$0 = $NF
- set $0 (the entire current input record)to the current value of the last field ($NF).
ORS = NR % n ? FS : RS
- using the ternary operator:expression ? return_this_if_true : return_this_otherwise
,set the OutputRecordSeparator to:
when NR % n evaluates true (i.e. returns value different than 0)
set ORS to the current value of FS (FieldSeparator - runs of white space
characters by default)
otherwise set it to RS (which defaults to a newline)
The x (an unitialized variable and thus a NULL string when used in concatenation)
is needed in order to handle correctly the output
when the last field is 0 (or an empty string).
This is because the assignement statement in awk
actually in this case returns the assigned value,
if $NF is 0, the rest of the && boolean statement
will be ignored.
我不完全确定你尝试做什么,试试这个:
I am not totally sure what you try do, try this: