在Bash中将多个文本文件串联为单个文件


305

将目录中的所有* .txt文件合并为一个大文本文件的最快,最实用的方法是什么?

目前,我与cygwin一起使用Windows,因此可以访问BASH。

Windows Shell命令也将很好,但是我怀疑是否有一个。

Answers:


537

这会将输出追加到all.txt

cat *.txt >> all.txt

这将覆盖all.txt

cat *.txt > all.txt

30
您可能会遇到将all.txt转换为all.txt的问题...有时我在grep中遇到此问题,不确定cat是否具有相同的行为。
rmeador

8
@rmeador是的,是的,如果all.txt已经存在,您将遇到此问题。通过为输出文件提供不同的扩展名或将all.txt移至其他文件夹来解决此问题。
罗伯特·格林纳

2
猫* .txt >> tmp; mv tmp all.txt(并确保all.txt事先不存在)
Renaud

16
我收到“参数列表太长”-猜想它不能处理40,000个以上的文件。
马特

32
避免将参数列表过长:echo *.txt | xargs cat > all.txt
5heikki 2014年

145

请记住,对于到目前为止给出的所有解决方案,shell决定了文件的连接顺序。对于Bash,IIRC,这是字母顺序。如果顺序很重要,则应该适当地命名文件(01file.txt,02file.txt等...),或以希望将其串联的顺序指定每个文件。

$ cat file1 file2 file3 file4 file5 file6 > out.txt

33

Windows shell命令type可以执行以下操作:

type *.txt >outputfile

Type type命令还将文件名写入stderr,>重定向操作符不会捕获这些文件名(但会显示在控制台上)。


2
请注意,如果将输出文件与原始文件放在同一目录中,则会导致重复,因为它还会将新的输出文件合并两次。
CathalMF

26

您可以使用Windows Shell copy来串联文件。

C:\> copy *.txt outputfile

从帮助中:

要附加文件,请为目标指定一个文件,但为源指定多个文件(使用通配符或file1 + file2 + file3格式)。


这是恕我直言的最干净的解决方案,基本上没有任何副作用,不幸的是,初学者可能不会绊倒:-(
Grmpfhmbl

OP要求Bash。
大富翁

2
你读问题了吗?“ Windows Shell命令也将很好...”
卡尔·诺鲁姆

8

请注意,因为这些方法都无法处理大量文件。我个人使用以下行:

for i in $(ls | grep ".txt");do cat $i >> output.txt;done

编辑:正如某人在评论中所说,您可以替换$(ls | grep ".txt")$(ls *.txt)

编辑:感谢@gnourf_gnourf专业知识,使用glob是遍历目录中文件的正确方法。因此,$(ls | grep ".txt")必须将亵渎性的表达式替换为*.txt(请参阅此处的文章)。

好的解决方案

for i in *.txt;do cat $i >> output.txt;done

1
为什么不for i in $(ls *.txt);do cat $i >> output.txt;done呢?
streamofstars

2
强制解析链接以及下降的投票(您应该获得不止一次的下降投票,因为这ls | grep是非常糟糕的反模式)。
gniourf_gniourf

得到我的支持是因为它允许在输出之前按文件名进行任意测试/操作,并且它快速,轻松且易于练习。(就我而言,我想要:对于*中的i;执行echo -e“ \ n $ i:\ n”; cat $ 1;完成)
Nathan Chappell

ls *.txt如果文件太多(参数列表过长的错误),是否会失败?
拉斐尔·阿尔梅达

6

使用shell最实用的方法是cat命令。其他方式包括

awk '1' *.txt > all.txt
perl -ne 'print;' *.txt > all.txt

1
对于大多数情况,这应该是正确的答案。如果有任何文本文件没有新的空行,则使用上述所有cat方法将相邻文件的最后一行和第一行连接起来。
mootmoot '16

6

这种方法怎么样?

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

由于OP表示文件位于同一目录中,因此您可能需要添加-maxdepth 1find命令中。
codeforester

1
非常适合处理大量文件,在这种情况下,接受的回复方法将失败

啊,我希望我知道这个加号和双重重定向的
含义

这应该是正确的答案。它将在shell脚本中正常工作。如果要对输出进行排序,这是一种类似的方法:sort -u --output="$OUTPUT_FILE" --files0-from=- < <(find "$DIRECTORY_NAME" -maxdepth 1 -type f -name '*.txt' -print0)
steveH

3
type [source folder]\*.[File extension] > [destination folder]\[file name].[File extension]

例如:

type C:\*.txt > C:\1\all.txt

这样将把所有txt文件保存在C:\文件夹中,并以all.txt的名称保存在C:\ 1文件夹中。

要么

type [source folder]\* > [destination folder]\[file name].[File extension]

例如:

type C:\* > C:\1\all.txt

这将获取文件夹中存在的所有文件,并将内容放在C:\ 1 \ all.txt中


0

您可以这样: cat [directory_path]/**/*.[h,m] > test.txt

如果{}用于包括要查找的文件的扩展名,则存在排序问题。


0

当您遇到将all.txt转换为all.txt的问题时,可以尝试检查all.txt是否存在,如果存在,请删除

像这样:

[ -e $"all.txt" ] && rm $"all.txt"


cat *.txt > all.txt >命令覆盖all.txt(如果存在),>>将数据添加到现有文件中
Oleg Bondarenko,

-4

所有这些都是令人讨厌的...

ls | grep *.txt | while read file; do cat $file >> ./output.txt; done;

简单的东西。


6
eek!不要那样做 做find . -iname "*.txt" -maxdepth 1 -exec cat {} >> out.txt \;
Chinmay Kanchi,2010年
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.