按行前缀拆分文件

slf*_*slf 6 linux bash grep command-line

我的数据如下所示:

60  xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
61  xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
62  xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
62  xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
62  xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
62  xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
62  xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
62  xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
62  xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
62  xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
62  xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
62  xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
62  xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
62  xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
63  xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
63  xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
63  xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
63  xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
63  xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
63  xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
63  xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
63  xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
63  xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
63  xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
63  xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
63  xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
64  xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Run Code Online (Sandbox Code Playgroud)

我想通过行前缀将其拆分为单独的文件..像这样:

file 60 contains all lines prefixed with "60"
file 61 contains all lines prefixed with "61"
...
Run Code Online (Sandbox Code Playgroud)

到目前为止,我想出的最好的想法是对所有行前缀进行 grep,然后循环遍历并将它们中的每一个 grep 放到一个单独的文件中,但它是一个相当大的文件,因此可能需要很长时间。也许有比循环和 grepping 更好的方法?某种grep分组方式?我知道如果每个部分之间都有标记,那么有一种方法可以将文件剪切掉,例如 --- 但我也不完全确定这是最好的方法。

Joh*_*024 13

如果调用输入文件data,一种解决方案是:

awk '{print>$1}' data
Run Code Online (Sandbox Code Playgroud)

在 中awk,第一个字段(列)称为$1。以上循环遍历每一行输入(awk隐式执行此操作)并将该行写入名称为第一个字段的文件。

更详细地:

  • 该命令放在大括号中。由于大括号前面没有限定符,因此该命令将在每个输入行上运行。

  • print没有参数的 command将打印整个输入行。

  • 该符号>表示将输出重定向到文件

  • 文件名被指定为$1which 再次引用输入行第一个字段中的任何文本。

因此,此命令将创建名为60, 61等的文件,这些文件将包含来自输​​入文件的相应行。

处理非常大的数据集

默认情况下,awk保持所有文件句柄打开,直到整个命令完成。因此,对于非常大的数据集,可能会超出系统对打开文件数量的限制。最简单的解决方案是在写入后使用追加并关闭每个文件:

awk '{print>>$1; close($1)}' data
Run Code Online (Sandbox Code Playgroud)

因为这使用>>(append),这将添加到现有数据文件而不是覆盖它们。如果这不是您想要的,请在运行此命令之前删除它们。