【发布时间】:2011-06-25 13:46:17
【问题描述】:
我有两个文件:file1 和 file2。如何将file2 的内容附加到file1 以便file1 的内容保持该过程?
【问题讨论】:
标签: linux shell file ubuntu append
我有两个文件:file1 和 file2。如何将file2 的内容附加到file1 以便file1 的内容保持该过程?
【问题讨论】:
标签: linux shell file ubuntu append
使用bash builtin redirection (tldp):
cat file2 >> file1
【讨论】:
sudo 预先附加到 cat 命令(并在出现提示时输入凭据)。
tee 程序:cat 1 | tee -a 2 3。您可以在--append(或简称-a)开关后放置任意数量的文件。
仅供参考,使用 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。
【讨论】:
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重定向,然后查找命令,没有找到,完成操作。
【讨论】:
cat file1 file2 > file1 - 这不会像你等待的那样工作。
>> 的命令将修改文件file1。 T.Rob 在解释他的答案方面做得非常出色,而不仅仅是竞相提交实际上不正确的东西。根据问题的文字,我认为cat file1 file2 > file3 是@asir 正在寻找的适当命令。
> 右侧的操作首先执行。因此,执行cat file1 file2 > file1 将首先破坏file1,然后尝试将现在为零长度的文件复制到自身。当您考虑操作可能并且应该发生的顺序时,这是有道理的,但它足够微妙以至于它让许多人感到惊讶。因此,如果不出意外,eumiro 和您已促使答案进一步改进。谢谢!
>>追加到文件中,>替换 文件。
你也可以不使用cat,但老实说cat 更具可读性:
>> file1 < file2
>> 将 STDIN 附加到 file1,< 将 file2 转储到 STDIN。
【讨论】:
另一种解决方案:
cat file1 | tee -a file2
tee 的好处是您可以附加到任意数量的文件,例如:
cat file1 | tee -a file2 file3 file3
会将file1 的内容附加到file2、file3 和file4。
来自手册页:
-a, --append
append to the given FILEs, do not overwrite
【讨论】:
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 only 命令相似的结果。
注意:如果您需要使用sudo,请这样做:
sudo bash -c 'cat file2 >> file1'
在命令前简单地添加sudo 的常用方法将失败,因为权限提升不会延续到输出重定向中。
【讨论】:
cat file2 | sudo tee -a file1 > /dev/null
试试这个命令:
cat file2 >> file1
【讨论】: