【问题标题】:Combine list of text files (too long), adding newline separator in between合并文本文件列表(太长),在其间添加换行符
【发布时间】:2019-01-11 11:52:36
【问题描述】:

我有一个包含约 300K 文本文件的目录,我想将它们连接成一个文件,并使用换行符 \n 分隔每个文件的内容。例如

file1 = 'i like apples'
file2 = 'john likes oranges'
output = 'i like apples\njohn likes oranges'

问题是由于文件较多,像

这样的命令
awk '{print}' dir/* combined.txt

抛出关于参数列表太长的错误。有什么快速解决这个问题的方法吗?我一直在尝试找到一种使用管道的方法,但到目前为止没有成功。

文本文件不以\n 结尾。

【问题讨论】:

  • 文件写入组合文件的顺序是否重要?
  • 不。因此,如果您有一个涉及 GNU parallel 或类似的解决方案,那就更好了!
  • 我认为并行写入单个文件时会很困难。
  • @shellter 这会引发Argument list too long 错误。
  • @shellter ...然后你就在“为什么不改用-exec”。

标签: bash unix text-files newline cat


【解决方案1】:

为避免冗长的命令行,您可以使用 shell 构造,例如 for 循环:

for f in dir/*; do cat "$f"; printf '\n'; done > combined.txt

如果合并文件中的文件顺序无关紧要,可以使用find 代替:

find dir -type f -exec sed -s '$s/$/\n/' {} + > combined.txt

这使用find -exec来最小化-exec中的命令被调用的次数,同时避免命令行太长。

sed -s '$s/$/\n' 用换行符替换文件中最后一行的结尾; -s 确保在提供多个作为参数时将更改应用于每个文件。

【讨论】:

  • 这差不多了,但它没有在文件之间添加\n 分隔符。有没有办法整合它?
  • @OrestXherija 你的意思是一个额外的换行符吗?您的示例仅显示文件内容之间的一个换行符。应该有一个空行吗?
  • 对不起,不,我的意思是像示例所指示的那样。
  • @OrestXherija 那么应该没问题,cat file1 file2 不会删除任何换行符。除非您的文件没有在最后一行的末尾有换行符,因此 don't adhere to the POSIX standard.
  • 啊,是的,这应该是问题所在。它们不会以 \n 结尾。
【解决方案2】:

处理大量文件的一种好方法是使用find,这在当今大多数发行版中都是相当标准的。类似的东西:

find ./dir -type f -exec bash -c "cat \{\} >> combined.txt && echo '' >> combined.txt"\;

我没有测试它,但这应该可以工作,并且优点是永远不会构建包含dir中所有文件的参数列表

【讨论】:

    【解决方案3】:

    使用 GNU Parallel 的解决方案:

    printf '%s\0' * | parallel -0 'cat {}; echo' > combined.txt
    

    小错误:combined.txt 将以未指定的 \n 结尾。

    不过,我的猜测是,您将受到 I/O 限制,因此 Benjamin W. 的解决方案可能会更快。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-03-17
      • 1970-01-01
      • 1970-01-01
      • 2015-06-08
      • 1970-01-01
      • 2016-08-22
      • 2015-10-27
      • 2017-03-04
      相关资源
      最近更新 更多