我有一个如下所示的文件:
# Time-averaged data for fix avetimeall
# TimeStep Number-of-rows
# Row c_gyrationchunkall
1000 3
1 2.09024e-14
2 4.88628
3 5.69321
2000 3
1 2.10518e-14
2 8.33702
3 8.83162
3000 3
1 1.96656e-14
2 12.1396
3 11.5835
...
在我的文件中,前三行始终是标题。在标题之后,我的文件列出了相同大小的数据块,每个数据块都以标签子标题开头。我想重新组织文件中的数据,以便将每个块中的数据发送到以该块标签的相关部分开始的行中,然后列出该块的相关数据值,所有数据都用空格分隔开。作为示例,我想将上面的示例转换为:
# Time-averaged data for fix avetimeall
# TimeStep c_gyrationchunkall
1000 2.09024e-14 4.88628 5.69321
2000 2.10518e-14 8.33702 8.83162
3000 1.96656e-14 12.1396 11.5835
...
我如何在 Bash 中执行此操作?我有一些 Bash 经验,但恐怕不足以快速处理这个问题......
使用任何 awk,无论
3
块中的行数是否可以变化:继Xavier Gs 回答下有关可读性风格偏好的讨论之后,这里有一个 awk 脚本,其编写风格与 shell 脚本相同(并包含在 shell 脚本中,因此它在外部的行为方式相同),但它将运行比 shell 脚本快*几个数量级,并且比 shell 脚本更健壮和可移植:
* 以下是在包含 90,000 条 OP 记录的文件上运行 bash 脚本与上述 awk 脚本的第三次运行计时结果:
使用Raku(以前称为 Perl_6)
用于
skip
暂时忘记标题行:上面是用 Raku(Perl 编程语言家族的成员)编写的答案。简而言之,
lines
读入、skip
ping 前 3 个标题行。每 4 行都一起rotor
编辑batch
,包括partial
文件末尾的最终“旋转”。当我们这样做时,让我们将每个rotor
/batch
分成空格分隔的words
。这些转子/批次 4 行,每行在空白处破碎,保存在
@
名为 的签名数组中@a
。最后(在第二个语句中),使用for
每个@a
位置进行迭代put
,并注意删除不需要的元素(通过索引括号[0,3,5,7]
)。输入示例:
示例输出:
put
关于标题行,用两个语句启动 Raku 代码可能很容易,例如put "Time-averaged data...";
等。但实际上,以下工作可以给出 OP 所需的输出:https://raku.org
使用AWK:
快速而肮脏的答案——随意运行
shellcheck
:用法:
./script_filename < input
限制:
根据问题中提到的警告并使用示例输入作为文件 q762948,您可以通过简单的 awk 命令来执行此操作: