如何将目录中的所有(文本)文件合并为一个?


89

我有14个文件全部都是一个文本的一部分。我想将它们合并为一个。怎么做?

Answers:


167

从技术上讲,这cat是应该做的(“连接”),即使大多数人只是将其用于将文件输出到stdout。如果给它多个文件名,它将按顺序输出所有文件名,然后可以将其重定向到一个新文件中。在所有文件都使用的情况下*(或者/path/to/directory/*如果您不在目录中),您的shell会将其扩展为所有文件名

$ cat * > merged-file

15
请注意,如果引用的命令编号方式使外壳*以“自然”顺序扩展,则引用的命令可能只会执行发布者想要的操作。如果您有“ file1.txt ... file9.txt ... file14.txt”,则该文件将不起作用,因为file1?.txt将在file1.txt和file2.txt之间进行排序。您必须将它们重命名为“ file01.txt ... file09.txt ... file14.txt”。再说echo *,如果你还不能肯定。
沃伦·杨

2
@Warren:好点(或者您可以使用zsh并设置其numeric_glob_sort选项)。
Gilles

2
@ warren-young正确,有用的警告评论。但是在我的实际情况下,顺序没有什么区别(因为文件仅包含简单的SQL语句,插入没有依赖性的数据记录)。
伊万

2
请注意,如果文件数超过一定限制,则可能会出现以下错误,例如-/ bin / cat:参数列表过长
Nupur,2015年

1
@ ARA1307仅当文件已经存在时;否则,将在外壳程序打开文件进行写入之前将glob扩展。不过,在这种情况下,好点是
Michael Mrozek

25

如果文件不在同一目录中,则可以在串联之前使用find命令:

find /path/to/directory/ -name *.csv -print0 | xargs -0 -I file cat file > merged.file

当文件已经订购并且想要合并它们以进行分析时,此功能非常有用。


更便携:

find /path/to/directory/ -name *.csv -exec cat {} + > merged.file

这可能会或可能不会保留文件顺序。


1
如果您有很多文件,这是一种方法。您可以避免出现“参数列表过长”的错误。
2014年

2
您需要-name“ * .csv”而不是-name * .csv-如果没有引号,它将失败。
彼得尼斯(Peteris),2016年

引号的需要取决于find命令的版本,特别是在find和awk中,当您使用Mac时,这是一个问题,两个程序的版本都有些旧。到目前为止,在ubuntu,fedora,debian和CentOS上,它在没有引号的情况下
都能

我希望当当前目录中没有与模式匹配的文件时,无引号的版本能够正常工作"*.csv",因为shell随后会将文字传递*find
RJHunter


9

命令

$ cat * > merged-file

实际上具有在合并中包含“合并文件”并创建失控文件的不良副作用。为了解决这个问题,可以将合并后的文件写入另一个目录。

$ cat * > ../merged-file

或使用模式匹配将忽略合并的文件;

$ cat *.txt > merged-file

14
cat * > merged-file工作正常。在创建文件之前先处理globs。如果merged-file已经存在,cat(至少是我的)将检测到它是输出文件,并拒绝读取它。如果文件已经存在,并且您稍后在管道中进行了重定向,那么显然它无法做到这一点,因此只有这样,您才能获得失控的文件。
凯文(Kevin)

cat无法检测文件是否为输出文件。重定向发生在外壳中;cat仅在标准输出上打印。
bfontaine

8

就像这里的其他人一样...您可以使用 cat

假设您有:

~/file01
~/file02
~/file03
~/file04
~/fileA
~/fileB
~/fileC
~/fileD

而您只file01想要file03fileAfileC

cat ~/file01 ~/file02 ~/file03 ~/fileA ~/fileB ~/fileC > merged-file

或者,使用括号扩展:

cat ~/file0{1..3} ~/file{A..C} > merged-file

或者,使用大括号扩展:

cat ~/file{0{1..3},{A..C}} > merged-file

或者您可以使用for循环:

for i in file0{1..3} file{A..C}; do cat ~/"$i"; done > merged-file

1
请注意,该字符串[01-03]不能用作全局模式。
库萨兰达

0

您可以指定pattern文件的,然后按以下步骤合并所有文件:

cat *pattern* >> mergedfile

0

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
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.