检测损坏的 JPEG:使用 find -exec 和 || 逻辑运算符

检测损坏的 JPEG:使用 find -exec 和 || 逻辑运算符
find . -maxdepth 1 -type f -exec identify -regard-warnings -verbose {} > /dev/null 2>&1 + || mv "$1" --backup=numbered {} -t "./Corrupted"   

我正在尝试使用上述方法检查当前目录中是否存在损坏的 JPEG 图像,如果存在,则将它们移动到另一个目录。

据我所知,到目前为止的问题是逻辑根本不起作用——||当identify以非零错误代码退出时,运算符右边的任何内容都不会执行,即使我使用简单的进行测试|| echo "File is bad"

我知道如果第一个谓词为真,我可以使用第二个-exec谓词来执行命令,但如果结果是假,-exec有没有办法执行命令?-exec

答案1

您可以执行 a bash -c,例如:

find [other parm] -exec bash -c 'identify -regard-warnings -verbose "$1" || exit 0 ; exit 1' onTheFlyScript {} \; -exec mv {} ./Corrupted \;

慢动作:

  • identify -regard-warnings -verbose "$1" || exit 0 ; exit 1反转输出逻辑identify(如果错误则为 0)
  • -exec bash -c '...' onTheFlyScript {} \;设置$0为“onTheFlyScript”(除非有错误,否则忽略)并$1设置为您的文件,因此如果文件损坏,它会成功(rc=0)
  • -exec mv {} ./Corrupted \; 如果第一个 exec 成功则执行,因此如果文件损坏

identify考虑到好文件的输出,我会-verbose在这里避免使用 parm,它只会减慢进程。

编辑:更简单的版本,不需要bash -c(在更复杂的情况下仍然是不可避免的):

find . -maxdepth 1 -name '*.jpg' \( -exec identify -quiet {} \; -o -exec mv -t ./Corrupted {} \+ \) 

换句话说,-exec当第一个失败时,将执行第二个。

正如卡米尔 (Kamil) 在评论中所说,你无法大规模识别文件,因为你需要每个文件的状态,但你确实可以将 a;和 a结合起来+,第二个确实是使用尽可能多的参数执行的。

答案2

我终于设法找出了卡米尔异种{}这确实有效。我主要通过将to 移到选项之前来实现这一点-t,尽管使用exec... +语法这也会导致以下错误:

发现:缺少“-exec”参数

因此我还必须切换到使用exec... \;语法,最终得到以下工作命令:

find . -maxdepth 1 -type f -iname "*.jpg" ! -exec identify -regard-warnings -verbose > /dev/null {} \; -exec mv {} -t ./Corrupted \;

需要切换-regard-warningsidentify以确保警告除了错误之外还以非零值退出(这对于移动仅标记警告的损坏图像是必要的),并且-verbose需要切换到 将警告和错误打印到屏幕上。如果您根本不想看到任何输出,则可以省略-verbose

答案3

对于简单的命令来说,使用起来find -exec很容易。但我认为对于更高级的东西,最好通过管道传输| while read var; do ...cmd1 $var; cmd2 "$var"; cmd3;...stuff...; done

find . -maxdepth 1 -type f | while read f; do identify "$f" > /dev/null 2>&1 || mv --backup=numbered "$f" ./Corrupted; done

答案4

尝试使用括号:

(find . -maxdepth 1 -type f -exec identify -regard-warnings -verbose {} > /dev/null 2>&1 +) || mv "$1" --backup=numbered {} -t "./Corrupted"   

相关内容