我遇到了一个我不太明白的情况。我有一堆递归结构的备份文件,我想计算其中的 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"