如何将多个文件的内容附加到一个文件中


174

我想将五个文件的内容照原样复制到一个文件中。我尝试使用cp为每个文件执行此操作。但这会覆盖从先前文件复制的内容。我也试过

paste -d "\n" 1.txt 0.txt

它没有用。

我希望我的脚本在每个文本文件的末尾添加换行符。

例如。文件1.txt,2.txt,3.txt。将1,2,3的内容放入0.txt

我该怎么做 ?



Answers:


308

您需要cat(连接的缩写)命令,并将shell重定向(>)放入输出文件

cat 1.txt 2.txt 3.txt > 0.txt

8
应该是>>对吗?以及为什么我的0.txt文件中的所有文本之前都有换行符?
2013年

1
您是否要保留0.txt的内容?
sehe

13
@blasto取决于。你会使用>>添加一个文件到另一个,其中> 覆盖与任何执导的到它的输出文件。至于换行符,文件中是否有换行符作为第一个字符1.txt?您可以通过使用找出od -c第一个字符是否为\n
激进主义

1
@ radical7谢谢。实际上,我的文件就像foo_1,foo_2,foo_3。我试图将您的代码修改为-cat“ $ filename _” {1,2,3}“。txt”,但是没有用。
2013年

1
@blasto您肯定会朝着正确的方向前进。Bash肯定接受{...}文件名匹配的形式,所以引号可能会使脚本中的内容有些混乱?我总是尝试ls在shell中使用类似的东西。正确执行命令后,我将其直接剪切-粘贴到脚本中即可。您可能还会发现该-x选项在脚本中很有用-在执行之前它将回显脚本中扩展的命令。
激进

97

对于仍然像我一样迷失于此帖子的那些人,另一种选择是使用find -exec

find . -type f -name '*.txt' -exec cat {} + >> output.file

就我而言,我需要一个更健壮的选项,该选项可以查看多个子目录,因此我选择使用find。分解:

find .

在当前工作目录中查找。

-type f

只对文件感兴趣,对目录等不感兴趣

-name '*.txt'

按名称减少结果集

-exec cat {} +

对每个结果执行cat命令。“ +”表示仅cat产生1个实例(thx @gniourf_gniourf)

 >> output.file

如其他答案所述,将目录内容附加到输出文件的末尾。


10
这个答案有很多缺陷。首先,*.txt必须对通配符加引号(否则,整个find命令,如所写的,是无用的)。另一个缺陷来自严重的误解:执行的命令不是 cat >> 0.txt {},而是cat {}。您的命令实际上等效于{ find . -type f -name *.txt -exec cat '{}' \; ; } >> 0.txt(我添加了分组,以便您了解实际情况)。另一个缺陷是find将查找文件0.txt,并且cat会说输入文件是输出文件而抱怨。
gniourf_gniourf 2014年

感谢您的更正。我的情况有些不同,我没有想到适用于此情况的一些陷阱。
mopo922 2014年

您应该将>> output.file命令放在最后,这样您就不会引起任何人(包括您自己)思考find将对cat {} >> output.file每个找到的文件执行的想法。
gniourf_gniourf 2014年

开始看起来真的很好!最后一个建议:使用-exec cat {} +而不是-exec cat {} \;,以便仅cat产生一个带有多个参数的实例(+由POSIX指定)。
gniourf_gniourf 2014年

3
好的答案和警告的词-我将我的修改为:find . -type f -exec cat {} + >> outputfile.txt并且即使目录只有50兆,也无法弄清楚为什么我的输出文件不会停止增长到演出。这是因为我一直将outputfile.txt附加到其自身!因此,只需确保正确命名该文件或将其完全放置在另一个目录中即可避免这种情况。
Thisisstackoverflow

43

如果您有某种输出类型,请执行以下操作

cat /path/to/files/*.txt >> finalout.txt

1
请记住,虽然您失去了保持合并顺序的可能性。如果您将文件命名为,这可能会影响您。file_1,,file_2file_11,因为文件排序的自然顺序。
emix

16

如果所有文件都在一个目录中,则只需执行

cat * > 0.txt

文件1.txt,2.txt,..将进入0.txt


Eswar已回答。请记住,虽然您失去了保持合并顺序的可能性。如果您将文件命名为,这可能会影响您。file_1,,file_2file_11,因为文件排序的自然顺序。
emix

10
for i in {1..3}; do cat "$i.txt" >> 0.txt; done

我找到此页面是因为我需要将952个文件合并为一个。如果您有许多文件,我发现此方法可以更好地工作。这将循环处理您需要的任何数字,并使用>>将每个数字附加到0.txt的末尾。


您可以在bash中使用括号扩展来编写cat {1,2,3} .txt >> 0.txt
mcheema

9

如果所有文件的名称都类似,则可以执行以下操作:

cat *.log >> output.log

5

另一种选择是sed

sed r 1.txt 2.txt 3.txt > merge.txt 

要么...

sed h 1.txt 2.txt 3.txt > merge.txt 

要么...

sed -n p 1.txt 2.txt 3.txt > merge.txt # -n is mandatory here

或者没有重定向...

sed wmerge.txt 1.txt 2.txt 3.txt

请注意,最后一行也要写merge.txt(不是wmerge.txt!)。您可以w"merge.txt"用来避免与文件名混淆,并-n用于静默输出。

当然,您也可以使用通配符来缩短文件列表。例如,对于如上例中的带编号文件,可以通过大括号指定范围:

sed -n w"merge.txt" {1..3}.txt

4

如果您的文件包含标头,并且想要在输出文件中将其删除,则可以使用:

for f in `ls *.txt`; do sed '2,$!d' $f >> 0.out; done

3

如果原始文件包含不可打印的字符,则在使用cat命令时它们将丢失。使用'cat -v',非可打印字符将被转换为可见的字符串,但是输出文件仍将在原始文件中不包含实际的非可打印字符。如果文件数量少,则替代方法可能是在处理非打印字符的编辑器(例如vim)中打开第一个文件。然后操纵到文件底部,然后输入“:r second_file_name”。这将拉入第二个文件,包括非打印字符。可以对其他文件执行相同的操作。读完所有文件后,输入“:w”。最终结果是,第一个文件现在将包含它最初执行的操作以及已读入文件的内容。


这不是很容易编写脚本。
FKEinternet

1

如果要将3个文件的内容附加到一个文件中,则以下命令将是一个不错的选择:

cat file1 file2 file3 | tee -a file4 > /dev/null

它将所有文件的内容合并到file4中,将控制台输出扔到/dev/null

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.