【问题标题】:Concatenating Files And Insert New Line In Between Files连接文件并在文件之间插入新行
【发布时间】:2012-01-01 06:18:02
【问题描述】:

我有多个文件想与cat 连接。 比方说

File1.txt 
foo

File2.txt
bar

File3.txt
qux

我想连接,使最终文件看起来像:

foo

bar

qux

而不是通常的cat File*.txt > finalfile.txt

foo
bar 
qux

正确的做法是什么?

【问题讨论】:

标签: linux unix cat


【解决方案1】:

你可以这样做:

for f in *.txt; do (cat "${f}"; echo) >> finalfile.txt; done

在运行上述命令之前,请确保文件 finalfile.txt 不存在。

如果你被允许使用awk,你可以这样做:

awk 'FNR==1{print ""}1' *.txt > finalfile.txt

【讨论】:

  • AWK '{print $0}' *.txt
  • 这有一个明显的缺陷,即在末尾(来自第一个选项)或开头(第二个选项)会有空行。不过,您可以使用awk 'FNR==1 && NR > 1 ...' 轻松防范这种情况。
  • 如果您将>finalfile.txt 放在done 之后,您可以覆盖而不是追加,这将消除在循环之前确保文件丢失或为空的要求。
【解决方案2】:

如果您有足够少的文件可以列出每个文件,那么您可以在 Bash 中使用 process substitution,在每对文件之间插入一个换行符:

cat File1.txt <(echo) File2.txt <(echo) File3.txt > finalfile.txt

【讨论】:

  • 漂亮!谢谢。
  • 这对我来说非常适合我的 Letsencrypt 证书来创建 .pem 文件。
  • 我正在尝试在 xargs 中执行此操作,但失败了,有什么提示吗? … | xargs -I{} kubectl -n alex exec {} -- cat blah.log &lt;(echo) &gt;&gt; blahblah.logs cat: /dev/fd/63: 没有这样的文件或目录,命令以退出代码 1 终止
  • @tuxErrante 我认为问题不在于 xargs 而是 kubectl,它采用命令远程运行,而 &lt;(echo) 在本地运行。也许-- bash -c "cat blah.log &lt;(echo)"
  • 它在 alpine shell 上不起作用,但是下面的可以,谢谢你的提示! sh -c "echo -e '\n\n' | cat - /../logs/a.log"
【解决方案3】:

如果是我这样做,我会使用 sed:

sed -e '$s/$/\n/' -s *.txt > finalfile.txt

在这个 sed 模式中,$ 有两个含义,首先它只匹配最后一个行号(作为应用模式的行范围),其次它匹配替换模式中的行尾。

如果您的 sed 版本没有 -s(单独处理输入文件),您可以将其全部作为循环来完成:

for f in *.txt ; do sed -e '$s/$/\n/' $f ; done > finalfile.txt

【讨论】:

  • 或者在 GNU sed 中:sed -s '$G' *.txt &gt; finalfile.txt
  • 只有一个流!这应该是公认的答案!
  • 小伙伴们小心点,我的电脑刚刚崩溃,因为我使用find 代替了*.txt,这意味着文件被附加到自身!
【解决方案4】:

这适用于 Bash:

for f in *.txt; do cat $f; echo; done

&gt;&gt;(附加)的答案相比,此命令的输出可以通过管道传输到其他程序中。

例子:

  • for f in File*.txt; do cat $f; echo; done &gt; finalfile.txt
  • (for ... done) &gt; finalfile.txt(括号是可选的)
  • for ... done | less(进入 less)
  • for ... done | head -n -1(这会去掉尾随的空行)

【讨论】:

    【解决方案5】:

    如果你愿意,你可以使用xargs,但主要思想还是一样的:

    find *.txt | xargs -I{} sh -c "cat {}; echo ''" > finalfile.txt
    

    【讨论】:

    • 谢谢。我发现xargs 比 bash 中的循环更容易使用。
    【解决方案6】:

    这就是我在 OsX 10.10.3 上的做法

    for f in *.txt; do (cat $f; echo '') >> fullData.txt; done
    

    因为没有参数的简单“echo”命令最终没有插入新行。

    【讨论】:

    • 这会将字符串放在文件末尾;如何将它插入到 每个 文件之间?
    【解决方案7】:

    在 python 中,这与文件之间的空行连接(, 禁止添加额外的尾随空行):

    print '\n'.join(open(f).read() for f in filenames),
    

    这是可以从 shell 调用并将输出打印到文件的丑陋的 python one-liner:

    python -c "from sys import argv; print '\n'.join(open(f).read() for f in argv[1:])," File*.txt > finalfile.txt
    

    【讨论】:

      猜你喜欢
      • 2015-09-24
      • 2013-09-24
      • 1970-01-01
      • 1970-01-01
      • 2017-08-21
      • 1970-01-01
      • 2023-02-02
      • 2011-10-15
      • 1970-01-01
      相关资源
      最近更新 更多