我有两个文件:file1
和 file2
。如何将file2
的内容附加到file1
中,以便file1
的内容在此过程中保留不变?
cat file2 >> file1
>>
操作符将输出附加到指定的文件中,如果文件不存在则创建该文件。
cat file1 file2 > file3
这个命令可以将两个或多个文件合并成一个。您可以拥有任意数量的源文件。例如:
cat *.txt >> newfile.txt
更新于20130902
在评论中,eumiro建议"不要尝试cat file1 file2 > file1
。”这样做可能不会得到预期的结果,因为在执行>
左边的命令之前,接收重定向的文件被准备好了。在此情况下,首先将file1
截断为零长度并打开以进行输出,然后cat
命令尝试将现在的零长度文件和file2
的内容连接到file1
中。结果是丢失了file1
的原始内容,并在其位置上放置了file2
的副本,这可能不是预期的结果。
更新于20160919
在评论中,tpartee建议链接到支持信息/来源。对于官方参考资料,我向亲切的读者指出位于linuxcommand.org的sh man页面,其中写道:
在执行命令之前,可以使用一种特殊符号由shell解释来重定向命令的输入和输出。
虽然这告诉读者他们需要知道的内容,但如果您不是逐字逐句地查找并解析语句,很容易错过。最重要的单词在这里是'before'(之前)。重定向在执行命令之前完成(或失败)。
例如cat file1 file2 > file1
的示例情况下,shell 首先执行重定向,以便在执行命令之前在环境中设置 I/O 句柄。
Ian Allen的网站提供了一个更友好的版本,其中详细介绍了重定向优先级,包括观察到即使没有命令也可以进行重定向的情况。将此传递给shell:
$ >out
该命令会创建一个名为 out 的空文件。Shell 首先设置 I/O 重定向,然后查找命令,发现没有,然后完成操作。
cat file1 file2 > file1
这个命令,它不会像你期望的那样工作。请注意不改变原意,并尽可能使语言更通俗易懂。 - eumirofile1
。T.Rob在解释他的答案时做得更好,而不仅仅是匆忙提交一个实际上是错误的内容。根据问题的文本,我认为cat file1 file2> file3
是@asir正在寻找的适当命令。 - dm78>
右侧的操作会首先执行。因此,执行cat file1 file2 > file1
将首先覆盖file1
,然后尝试将现在长度为零的文件复制到自身。当您考虑操作应该发生的顺序时,这是有道理的,但足够微妙,以至于它会让很多人感到惊讶。因此,如果没有其他事情,eumiro和您已经促使了答案的进一步改进。感谢您! - T.Rob>>
将向文件追加内容,而>
则会替换文件。 - rinogo注意: 如果需要使用 sudo,请执行以下操作:
sudo bash -c 'cat file2 >> file1'
通常的方法是将 sudo
直接添加到命令前,但这样做会失败,因为特权提升并不会传递到输出重定向中。
cat file2 | sudo tee -a file1 > /dev/null
。这句话的意思是将 "file2" 的内容添加到 "file1" 中,并使用超级用户权限执行此操作,最后将输出重定向到 "/dev/null" 中。 - ianw尝试使用这个命令:
cat file2 >> file1
仅供参考,使用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
的输出)。
如评论中ngks所指出的那样,不好的一点是ddrescue可能不会默认安装,因此您需要手动安装它。另一个麻烦之处在于,你的存储库中可能有两个版本的ddrescue:请参阅这个askubuntu问题了解更多信息。你想要的版本是GNU ddrescue,在基于Debian的系统中的软件包名为gddrescue
:
sudo apt install gddrescue
对于其他发行版,请检查您的软件包管理系统以获取 GNU 版本的 ddrescue。
另一种解决方案:
tee < file1 -a file2
tee
有一个好处,就是可以将一个文件追加到多个文件中,例如:
tee < file1 -a file2 file3 file3
将file1
的内容追加到file2
、file3
和file4
中。
与此相反的是
cat file2 file3 file4 >> file1
将多个文件追加到一个文件中的应用程序。
来自手册页面:
-a, --append
append to the given FILEs, do not overwrite
Zsh 特定:您也可以不使用cat
,但说实话cat
更易读:
>> file1 < file2
>>
将STDIN附加到file1
,而<
将file2
转储到STDIN。
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
time (find . -maxdepth 1 -type f -name 'bigFile*' -print0 | xargs -0 cat -- > outFile1)
,它应该会产生与你仅使用cat命令相似的结果。 - JoshMc
tee
程序:cat 1 | tee -a 2 3
。在--append
(或简称为-a
)开关后面可以加入任意数量的文件。 - Stefan van den Akker