连续管道和执行命令的结果不同?

连续管道和执行命令的结果不同?

我是 bash 的新手,所以如果这很愚蠢,我深表歉意。

我正在跟进将 HEIC 图像转换为 JPG 的指南,我很困惑为什么运行find和连续地通过管道传输towc的结果会产生不同的结果。具体来说,对于findwc

temp=$(find . -maxdepth 1 -name "*.HEIC")
count=$(wc -l $temp) 

$count正如我所期望的,计算结果为包含字数的文件列表。但是,如果我像文章中那样写:

count=$(find . -maxdepth 1 -name "*.HEIC" | wc -l)

然后它计算具有 .HEIC 扩展名的文件的计数。

答案1

从 '男人厕所'

wc [选项]...[文件]...

打印每个 FILE 的换行符、字数和字节数,如果指定了多个 FILE,则打印总行数。

count=$(wc -l $temp) 

评估为

count=$(wc -l /path/to/file1 /path/to/file2 ) 

因此它计算所有文件中的行数而不是文件数。
你应该将第二行更改为

count=$(echo "$temp" | wc -l) 

答案2

因为 bash 不是 PowerShell(或者其他什么,我不知道),并且left | right不会导致使用作为命令行参数right输出的行或单词进行调用,而是使用从正在写入其内容的管道重定向的标准输入来运行输出。并且也将同时运行,而不是顺序运行。leftrightleftleftright

wc -l不带任何参数调用时files,它仅计算其标准输入中的行数。seq 1 2 | wc -l将打印2.

无论如何,find . ... | wc -l很容易被包含换行符的文件名破坏,(不幸的是)这是非常允许的。使用 GNU find,您可以通过以下方式解决这个问题:

count=$(find . ... -name '*.HEIC' -printf _ | wc -c)

# or just
count=$(find . ... -name '*.HEIC' -printf _); count=${#count}

答案3

还值得注意的是,$(…)修剪掉所有尾随换行符,而 echo 添加换行符,因此如果输出以find空行结尾或者完全为空,则两种方法给出的答案可能会有所不同。

特别是,$( echo "$temp" | wc -l )永远不会是0。

相关内容