find 和 md5sum 没有产生任何输出(find -o limit?)

find 和 md5sum 没有产生任何输出(find -o limit?)

我遇到了一个我不太明白的情况。我有一堆递归结构的备份文件,我想计算其中的 md5。当我添加一些额外的文件扩展名时,进程退出(退出代码 0)而不产生任何输出。

find . -type f -iname "*.3gp" -o -iname "*.avi" -o -iname "*.mov" -o -iname "*.mp4" -print0 | xargs -0 md5sum
find . -type f -iname "*.3gp" -o -iname "*.avi" -o -iname "*.mov" -o -iname "*.mp4" -o -iname "*.mpg" -print0 | xargs -0 md5sum

第一个工作正常,第二个没有产生任何输出。我什至在没有 mpg 文件的目录中尝试过它,行为相同。

要查找的参数数量有限制吗?我正在运行 OSX,并从 Macports 安装了 md5sum。

额外的信息

管道似乎有些奇怪,我倾向于归咎于文件名。对另一个文件夹的进一步调查显示,find 命令似乎有效,并且有 129 个视频文件,其中 1 个是 .mpg。当我尝试 find+md5sum 时,它仅在 1 个文件后返回。我在其他仅包含图片的文件夹中运行了类似的命令,并且运行良好(找到 80k 文件,产生 80k 哈希值)。

Pictures@2006$ find . -type f -iname "*.3gp" -o -iname "*.avi" -o -iname "*.mov" -o -iname "*.mp4" | wc -l
 128
Pictures@2006$ find . -type f -iname "*.3gp" -o -iname "*.avi" -o -iname "*.mov" -o -iname "*.mp4" -o -iname "*.mpg" | wc -l
 129
Pictures@2006$ find . -type f -iname "*.3gp" -o -iname "*.avi" -o -iname "*.mov" -o -iname "*.mp4" -o -iname "*.mpg" -print0 | xargs -0 md5sum
 c21a78f2b2d5ca773b47647315ad91f8  ./pending photos/Video [%]/P007.MPG
Pictures@2006$

我还注意到要处理的第二个文件名包含标点符号、加号和非 ASCII 字符。错误可能是由于文件命名造成的吗?有什么解决方法吗?

/Esplai/+Nou/20060604 Dinar d'últim dia d'esplai[Barbacoa al torrent de l'Escaiola]/MVI_7702.AVI

答案1

如果命令中的运算符表达式find没有用-o( 表示或者) 或者-a-a),他们之间有一个隐含的关系。并且-a比 结合得更紧密-o,所以

find . -type f -iname "*.3gp" -o -iname "*.avi" -o -iname "*.mov" \
     -o -iname "*.mp4" -o -iname "*.mpg" -print0 

将被解析为

find . '(' -type f -a -iname "*.3gp" ')' -o -iname "*.avi" -o -iname "*.mov" \
     -o -iname "*.mp4" -o '(' -iname "*.mpg" -a -print0 ')'

所以-print0只会打印匹配的文件(和目录!)*.mpg。这就是为什么使用此命令,您只处理一个文件,而不是您期望的 129 个文件。

您可以使用括号(用引号括起来,因为它们对于 shell 来说也是特殊的)来更改分组:

find . -type f '(' -iname "*.3gp" -o -iname "*.avi" -o -iname "*.mov" \
     -o -iname "*.mp4" -o -iname "*.mpg" ')' -print0 | xargs -0 md5sum

答案2

首先我要提一下 -print0 是非标准的,也不是最好的解决方案。更好的是使用“execplus”,例如

find dir -type f -exec cmd {} +

然而,您的主要问题是运算符具有优先级,并且您的 -print 仅与姓氏主要“与”。

所以正确的方法是将 -o 红色原色放在括号中:

find dir ( -name '*.x1' -o -name '*.x2' ) -exec cmd {} +

如果需要,您当然可以添加更多 -o -type 运算符。

答案3

我认为当前目录中有一个与"*.mpg"通配符匹配的文件,并且扩展为令人困惑的内容find,例如... -o iname A Movie about Birds.mpg.如果您使用单引号,例如'*.mpg'而不是双引号"*.mpg",则不会进行通配符扩展,并且find会看到*.mpg

要查看发生了什么,可以echo在开头添加一个 ( echo find ...),或者将结果通过管道传输到| tr "\000" "\n"

相关内容