连接数千个文件:> vs >>

Ame*_*ina 7 shell find io-redirection xargs

对于以下问题,我在 StackOverflow 上发现了两个看似矛盾的答案:

第一个问题的最佳答案表明:

find . -name *.txt -print0 | xargs -0 cat >> out.txt

而第二个问题的最佳答案表明:

find . -name *.txt -print0 | xargs -0 cat > out.txt

据我所知,第一个是正确的,因为它使用>>(append) 运算符,但不是第二个,因为它使用了>我认为只是将输出重定向到文件的运算符。然而,第二个答案有更多的票数(10)并且也被接受了,没有评论。两个答案都正确吗?为什么?那么拥有这两个运营商的目的是什么?

slm*_*slm 16

第二个例子:

find . -name '*.txt' -print0 | xargs -0 cat > out.txt
Run Code Online (Sandbox Code Playgroud)

是完全合法的,out.txt每次运行时都会重新创建文件,而第一个将连接到out.txt它是否运行。但是这两个命令基本上都在做同样的事情。

令人困惑的是这个问题xargs -0 cat。人们认为重定向到out.txt是该命令的一部分,而实际上并非如此。重定向是xargs -o cat在通过 STDIN 接收输入之后发生的,然后将该输出作为单个流输出到 STDOUT。将xargs是优化的文件的cat'ing不是他们的输出。

这是一个例子,可以说明我在说什么。如果我们在文件的输出和输出pv -l之间插入一个,我们可以看到 cat 写了多少行。xargs -0 catout.txt

例子

为了说明这一点,我创建了一个包含 10,000 个文件的目录。

for i in `seq -w 1 10000`;do echo "contents of file$i.txt" > file$i.txt;done
Run Code Online (Sandbox Code Playgroud)

每个文件看起来都类似于:

$ more file00001.txt 
contents of file00001.txt
Run Code Online (Sandbox Code Playgroud)

输出pv

$ find . -name '*.txt' -print0 | xargs -0 cat | pv -l > singlefile.rpt
  10k 0:00:00 [31.1k/s] [  <=> 
Run Code Online (Sandbox Code Playgroud)

正如我们所看到的,我的singlefile.rpt文件中写入了 10k 行。如果xargs向我们传递大块输出,那么我们会通过减少呈现给pv.


Hau*_*ing 5

那么拥有这两个运营商的目的是什么?

这很简单:因为有不同的用例。有时首先将目标文件截断到大小为 0 很有用,有时(例如日志文件)将数据附加到文件更有意义。

在这种情况下,追加没有意义。您需要一个与您选择的文件内容完全相同的文件,而不是“一个在开头包含任何数据而在结尾包含所选文件内容的文件”。