如何从外壳程序在Linux中将一个文件附加到另一个文件?


418

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

Answers:


610

使用bash内置重定向(tldp)

cat file2 >> file1

2
如何处理目标文件不归您所有,您需要使用sudo?
2014年

1
@BijayRungta:听起来您已经回答了自己的问题。你会预先挂起sudocat命令(如果提示输入凭据)。
大卫

您需要... chmod 777 / etc / default / docker以授予您对该文件的写权限-确保完成后恢复旧文件的权限
danday74 '16

1
@Sigur:除非有一种方法可以将输出一次定向到两个文件,否则它将涉及两次命令调用。
大卫

2
@Sigur或查看tee程序:cat 1 | tee -a 2 3。您可以在--append(或-a简称为)切换之后放置任意数量的文件。
Stefan van den Akker,

291

cat file2 >> file1

>>运营商将输出追加到指定的文件或创建命名的文件,如果它不存在。

cat file1 file2 > file3

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

cat *.txt >> newfile.txt

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

更新20160919
在意见中,tpartee建议链接到支持信息/源。作为权威参考,我将种类的读者定向到linuxcommand.org 上的sh手册页,其中指出:

在执行命令之前,可以使用由Shell解释的特殊符号来重定向其输入和输出。

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

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

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

$ >out

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


17
@asir-不要尝试cat file1 file2 > file1-这可能无法正常工作,因为您可能正在等待。
eumiro'2

5
实际上,这正是他所需要的。他说“不覆盖当前文件1”。前三应答者完全忽略了这部分的质询,并建议使用命令>>修改该文件file1。T.Rob在解释自己的答案方面做得非常出色,而不仅仅是竞速提交事实上是不正确的内容。根据问题的内容,我认为这cat file1 file2 > file3是@asir正在寻找的适当命令。
2013年

大卫,谢谢您的客气!@eumiro上面指出但没有详细说明的是,>首先执行右边的操作。因此,执行cat file1 file2 > file1将首先破坏,file1然后尝试将现在为零长度的文件复制到自身上。当您考虑操作可能发生和应该发生的顺序时,这是很有意义的,但是这种操作很细微,以至于让很多人惊讶。因此,如果没有其他问题,eumiro和您已经提示了答案的进一步改进。感谢那!
T.Rob

不要尝试使用cat file1 >> file1,这将导致文件被递归重写,我错误地这样做了,并且在短短几秒钟之内,已经从之前的几十行中将5000万行插入到文件中。
Hendra Uzia

同样,只是为了使其更加简洁,如果“新文件”已经存在,则将其>> 追加到该文件并> 替换该文件。
rinogo '18

43

注意:如果需要使用sudo,请执行以下操作:

sudo bash -c 'cat file2 >> file1'

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


6
另一个常见的成语是cat file2 | sudo tee -a file1 > /dev/null
ianw


13

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

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

logfile是重要的一点。您可以Ctrl-C通过再次指定完全相同的命令来中断并恢复该过程,然后ddrescue将从中断处读取logfile并恢复。该-o A标志告诉ddrescue从输出文件()中的字节A开始file1。因此,wc --bytes file1 | awk '{ print $1 }'只需提取file1以字节为单位的大小即可(如果需要,您可以将其粘贴到输出中ls)。

正如ngks在评论中指出的那样,缺点是默认情况下可能不会安装ddrescue,因此您必须手动安装它。另一个复杂之处是您的存储库中可能存在ddrescue的两个版本:有关更多信息,请参见此askubuntu问题。您想要的版本是GNU ddrescue,在基于Debian的系统上是一个名为的软件包gddrescue

sudo apt install gddrescue

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


1
为了新用户的利益:ddrescue是一种GNU工具,但在Linux,Mac或其他类似Unix的系统上可能不存在。POSIX或任何其他标准似乎都没有要求ddrescue。

2

另一个解决方案:

cat file1 | tee -a file2

tee 您可以将其附加到尽可能多的文件中,例如:

cat file1 | tee -a file2 file3 file3

将追加的内容file1file2file3file4

从手册页:

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

0

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的命令相似。
JoshMc

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.