为什么这不起作用?“ls *.txt | xargs cat > all.txt”(将所有文件合并到单个 txt 文档中)

为什么这不起作用?“ls *.txt | xargs cat > all.txt”(将所有文件合并到单个 txt 文档中)

为什么这不起作用?

ls *.txt | xargs cat > all.txt

(我想将所有文本文件的内容合并到单个“all.txt”文件中。)使用 -exec 的 find 也应该可以工作,但我真的很想了解 xargs 语法。

谢谢

答案1

ls *.txt | xargs cat >> all.txt

可能会更好一些,因为它会附加到 all.txt 而不是在每个文件之后再次创建它。

顺便说一句,cat *.txt >all.txt也可以。:-)

答案2

如果你的某些文件名包含“,”或空格,xargs则会失败,因为分隔符问题

一般来说,永远不要xargs在没有 -0 的情况下运行,因为有一天它会回来咬你。

考虑使用 GNU Parallel:

ls *.txt | parallel cat > tmp/all.txt

或者如果你愿意:

ls *.txt | parallel cat >> tmp/all.txt

了解有关 GNU Parallel 的更多信息http://www.youtube.com/watch?v=OpaiGYxkSuQ

答案3

all.txt是同一目录中的文件,因此当 cat 想要从同一文件写入同一文件时会感到困惑。

另一方面:

ls *.txt | xargs cat > tmp/all.txt

这将从当前目录中的文本文件读取到子目录中的 all.txt 中(不包含在内*.txt)。

答案4

您还可能会遇到命令行长度限制。使用的原因之一xargs是它将输入拆分为安全的命令行大小的块。因此,想象一下目录中有数十万个 .txt 文件的情况。 ls *.txt将失败。您需要执行

ls | grep .txt$ |xargs cat > /some/other/path/all.txt

.txt$在这种情况下,是一个正则表达式,匹配以 .txt 结尾的所有内容(所以它不完全像*.txt,因为如果你有一个名为的文件atxt,那么*.txt就不会匹配它,但正则表达式会匹配。)

使用另一条路径的原因是,正如其他答案指出的那样,all.txt 与模式匹配,*.txt因此输入和输出之间会发生冲突。

请注意,如果您的文件'名称中包含 (这可能是导致unmatched single quote错误的原因),您可能需要执行

ls | grep --null .txt$ | xargs -0 cat > /some/other/path/all.txt

--null 选项告诉 grep 使用由\0(aka null) 字符分隔的输出,而不是默认的换行符,而-0`xargs 选项告诉它期望其输入采用相同的格式。即使文件名中包含换行符,这也会起作用。

相关内容