【问题标题】:How to append one file to another in Linux from the shell?如何从 shell 将一个文件附加到 Linux 中的另一个文件?
【发布时间】:2011-06-25 13:46:17
【问题描述】:

我有两个文件:file1file2。如何将file2 的内容附加到file1 以便file1 的内容保持该过程?

【问题讨论】:

    标签: linux shell file ubuntu append


    【解决方案1】:

    使用bash builtin redirection (tldp):

    cat file2 >> file1
    

    【讨论】:

    • 你怎么做目标文件不归你所有,你需要使用sudo?
    • @BijayRungta:听起来您回答了自己的问题。您需要将 sudo 预先附加到 cat 命令(并在出现提示时输入凭据)。
    • 您需要... chmod 777 /etc/default/docker 为自己授予对该文件的写入权限 - 完成后请务必恢复旧文件权限
    • @Sigur:除非有办法一次将输出定向到两个文件,否则将涉及对命令的两次调用。
    • @Sigur 或查看tee 程序:cat 1 | tee -a 2 3。您可以在--append(或简称-a)开关后放置任意数量的文件。
    【解决方案2】:

    仅供参考,使用 ddrescue 提供了一种可中断的方式来完成任务,例如,如果您有大文件并且需要暂停然后稍后继续:

    ddrescue -o $(wc --bytes file1 | awk '{ print $1 }') file2 file1 logfile
    

    logfile 是重要的位。您可以使用Ctrl-C 中断该过程并通过再次指定完全相同的命令来恢复它,ddrescue 将读取logfile 并从它停止的地方恢复。 -o A 标志告诉 ddrescue 从输出文件 (file1) 中的字节 A 开始。所以wc --bytes file1 | awk '{ print $1 }' 只是以字节为单位提取file1 的大小(如果你愿意,你可以粘贴ls 的输出)。

    正如 cmets 中的 ngks 所指出的,缺点是可能不会默认安装 ddrescue,因此您必须手动安装它。另一个复杂之处是您的存储库中可能有两个版本的 ddrescue:请参阅this askubuntu question 了解更多信息。您想要的版本是 GNU ddrescue,在基于 Debian 的系统上是名为 gddrescue 的软件包:

    sudo apt install gddrescue
    

    对于其他发行版,请检查您的软件包管理系统是否有 GNU 版本的 ddrescue。

    【讨论】:

    • 为了新用户的利益:ddrescue 是一个 GNU 工具,但它可能不存在于您的 Linux、Mac 或其他类 unix 系统上。 POSIX 或任何其他标准似乎都不需要 ddrescue。
    【解决方案3】:

    cat file2 >> file1

    >> 运算符将输出附加到指定文件,如果指定文件不存在,则创建该文件。

    cat file1 file2 > file3

    这会将两个或多个文件连接为一个。您可以根据需要拥有任意数量的源文件。例如,

    cat *.txt >> newfile.txt

    更新 20130902
    在 cmets 中,eumiro 建议“不要尝试cat file1 file2 > file1”。这可能不会导致预期结果的原因是接收重定向的文件是在执行> 左侧的命令之前准备好的。在这种情况下,首先file1 被截断为零长度并打开输出,然后cat 命令尝试将现在为零长度的文件加上file2 的内容连接到file1。结果是file1 的原始内容丢失了,取而代之的是file2 的副本,这可能不是预期的。

    更新 20160919
    在 cmets tpartee 中建议链接到支持信息/来源。对于权威参考,我将善良的读者引导至 linuxcommand.org 上的sh man page,其中指出:

    在执行命令之前,它的输入和输出可能会被重定向 使用由 shell 解释的特殊符号。

    虽然这确实告诉读者他们需要知道什么,但如果您不寻找它并逐字解析语句,很容易错过。这里最重要的词是“之前”。重定向完成(或失败)命令执行之前。

    cat file1 file2 > file1 的示例情况下,shell 首先执行重定向,以便 I/O 句柄在命令执行之前执行的环境中就位。

    可以在 Ian Allen 的网站上以 Linux 课件的形式找到更友好的版本,其中详细介绍了重定向优先级。他的I/O Redirection Notes 页面对这个话题有很多话要说,包括观察到即使没有命令也可以重定向。将其传递给 shell:

    $ >out
    

    ...创建一个名为 out 的空文件。 shell首先设置I/O重定向,然后查找命令,没有找到,完成操作。

    【讨论】:

    • @asir - 不要尝试cat file1 file2 > file1 - 这不会像你等待的那样工作。
    • 其实这正是他所需要的。他说“不覆盖当前文件1”。前三位回答者完全忽略了这部分问题,并建议使用>> 的命令修改文件file1。 T.Rob 在解释他的答案方面做得非常出色,而不仅仅是竞相提交实际上不正确的东西。根据问题的文字,我认为cat file1 file2 > file3 是@asir 正在寻找的适当命令。
    • 谢谢你的好话,大卫! @eumiro 在上面指出但没有详细说明的是,> 右侧的操作首先执行。因此,执行cat file1 file2 > file1 将首先破坏file1,然后尝试将现在为零长度的文件复制到自身。当您考虑操作可能并且应该发生的顺序时,这是有道理的,但它足够微妙以至于它让许多人感到惊讶。因此,如果不出意外,eumiro 和您已促使答案进一步改进。谢谢!
    • 另外不要试试cat file1 >> file1,这会导致文件被递归重写,我错误地这样做了,就在几秒钟内,5000万行已从之前的几十行中放入文件中。
    • 另外,为了更简洁,如果“新文件”已经存在,>>追加到文件中,>替换 文件。
    【解决方案4】:

    你也可以不使用cat,但老实说cat 更具可读性:

    >> file1 < file2

    >>STDIN 附加到 file1<file2 转储到 STDIN

    【讨论】:

    • @user202729 你说得对,它在 bash 中不起作用。它确实在 zsh 中工作。
    【解决方案5】:

    另一种解决方案:

    cat file1 | tee -a file2
    

    tee 的好处是您可以附加到任意数量的文件,例如:

    cat file1 | tee -a file2 file3 file3
    

    会将file1 的内容附加到file2file3file4

    来自手册页:

    -a, --append
           append to the given FILEs, do not overwrite
    

    【讨论】:

      【解决方案6】:

      cat 可能是一个简单的解决方案,但是当我们连接大文件时会变得很慢,find -print 是为了拯救你,尽管你必须使用一次 cat。

      amey@xps ~/work/python/tmp $ ls -lhtr
      total 969M
      -rw-r--r-- 1 amey amey 485M May 24 23:54 bigFile2.txt
      -rw-r--r-- 1 amey amey 485M May 24 23:55 bigFile1.txt
      
       amey@xps ~/work/python/tmp $ time cat bigFile1.txt bigFile2.txt >> out.txt
      
      real    0m3.084s
      user    0m0.012s
      sys     0m2.308s
      
      
      amey@xps ~/work/python/tmp $ time find . -maxdepth 1 -type f -name 'bigFile*' -print0 | xargs -0 cat -- > outFile1
      
      real    0m2.516s
      user    0m0.028s
      sys     0m2.204s
      

      【讨论】:

      • 您为 find/cat 组合命令报告的时间节省是因为您只为打印文件名称的 find 命令计时。尝试像这样对整个命令进行计时:time (find . -maxdepth 1 -type f -name 'bigFile*' -print0 | xargs -0 cat -- > outFile1),它应该会产生与您的 cat only 命令相似的结果。
      【解决方案7】:

      注意:如果您需要使用sudo,请这样做:

      sudo bash -c 'cat file2 >> file1'

      在命令前简单地添加sudo 的常用方法将失败,因为权限提升不会延续到输出重定向中。

      【讨论】:

      • 另一个常见的成语是cat file2 | sudo tee -a file1 > /dev/null
      【解决方案8】:

      试试这个命令:

      cat file2 >> file1
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-08-15
        • 2020-03-19
        • 2018-12-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-02-15
        相关资源
        最近更新 更多