【问题标题】:How do I insert a new line before concatenating?如何在连接之前插入新行?
【发布时间】:2011-10-15 09:02:50
【问题描述】:

我有大约 80000 个文件要连接。这个:

cat files_*.raw >> All

非常快,而以下:

for f in `ls files_*.raw`; do cat $f >> All; done;

非常慢。由于这个原因,我试图坚持第一个选项,除了我需要能够在每个文件连接到All 后插入一个新行。有什么快速的方法吗?

【问题讨论】:

    标签: linux file unix command-line ubuntu


    【解决方案1】:

    怎么样

    ls files_*.raw | xargs -L1 sed -e '$s/$/\n/' >>ALL
    

    当你连接它们时,这将在每个文件的末尾插入一个额外的换行符。

    如果您不关心连接顺序,还有一个并行版本:

    find ./ -name "*.raw" -print | xargs -n1 -P4 sed -e '$s/$/\n/' >>All
    

    【讨论】:

    • 太棒了!完美运行。为了以防万一,我还添加了一个并行版本。谢谢。
    • 小心并行化,因为你的输出会混合在 ALL 文件中——不确定你是否关心。
    • 实际上,这应该没问题,因为我正在提取有关单个文件的一些统计信息,并且在这种情况下顺序无关紧要。在一个不相关的案例中,我不知道为什么答案在没有评论的情况下被否决!
    • +1 的好答案,太糟糕了,我不能再做一个来弥补神秘的反对票。 Downvoter - 请发表评论!
    • @Legend - 重新你的并行版本:如果你要使用find | xargs,你应该(几乎?)总是使用 NUL 终止选项find .... -print0 | xargs -0 .... 这样你就不会中断如果有任何名称中带有空格的文件或目录。
    【解决方案2】:

    第二个命令可能会很慢,因为您打开“全部”文件以追加 80000 次,而第一个命令是 1 次。尝试第二个命令的简单变体:

    for f in `ls files_*.raw`; do cat $f ; echo '' ; done >> All
    

    【讨论】:

    • 如果你真的想使用这样的 for 循环(它对可以处理的文件数量有限制),那么至少摆脱 ls 并确保引用你的文件名,所以:for f in files_*.raw; do cat "$f" ; echo '' ; done >> All
    • +1 感谢您的努力,但我已经有了这个版本,但正如 Soren 所说,我必须完全避免 ls 以及 for 循环。
    【解决方案3】:

    我不知道为什么会慢,但我认为你没有太多选择:

    for f in `ls files_*.raw`; do cat $f >> All; echo '' >> All; done
    

    【讨论】:

    • 为您的时间+1。就像我在其他 cmets 中提到的那样,我试图避免 for 循环。
    【解决方案4】:

    awk 每次打开另一个文件进行处理,FRN 等于 0,所以:

    awk '(0==FRN){print ""} {print}' files_*.raw >> All
    

    注意,这一切都在一个 awk 进程中完成。性能应该接近问题中的 cat 命令。

    【讨论】:

      猜你喜欢
      • 2012-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多