查找“损坏”文件,将 if 嵌套在 find 命令中

查找“损坏”文件,将 if 嵌套在 find 命令中

我试图在目录结构中查找“损坏”文件,即文件命令将解释为“数据”的文件。这是我一直尝试运行但失败的命令:

$ find . -type f -exec if [[ $(file \{} | cut -f2 -d':') == " data" ]] \; then echo " \{}  is CORRUPT" \; else echo " \{} is DATA" \; fi \;
find: paths must precede expression: then

有谁知道我在这里做错了什么?

我意识到我从未见过参数if内部-exec。有可能吗?

基本上,我试图找到符合该条件的文件(文件将其报告为“数据”,而不标识特定的文件类型),然后列出它们,以便我可以在删除之前进行分析。

答案1

您需要一个 shell 来解释这些if/then/else构造或运行这些管道(尽管您在这里并不真正需要这些):

find . -type f -exec sh -c '
  for file do
    case $(file -b "$file") in
      (data) printf "%s is CORRUPT\n" "$file";;
         (*) printf "%s is DATA\n" "$file";;
    esac
  done' sh {} +

file(就像在你的问题中一样,当说时它会打印“CORRUPT” data。但我不确定这就是你的意思)。

无论你做什么,都不要{}像其他人建议的那样包含在 shell 代码中!这将是非常危险的(并且不可移植),因为例如一个名为 的文件$(rm -rf "$HOME")会让您删除整个主目录。

答案2

不是您标题的确切答案(在查找中嵌套 if ),但出于所有目的,这是比在查找中插入整个 shell 脚本更好的解决方案。

另请注意,在泛型内部,sh测试[[不起作用,并且[=.或者使用正则表达式匹配==~,因为我相信您确实需要。因此,您需要一个 bash shell,如果您已经在 bash shell 中,那么它就没有多大意义。无论如何,这比启动新 shell 更快:

#!/bin/bash
while IFS= read -rd '' file; do
    if [[ $(file "$file" | cut -f2 -d':') =~ " data" ]]; then
        printf "%s is CORRUPT\n" "$file"
    else
        printf "%s is DATA\n" "$file"
    fi
done < <(find . -type f -print0)

注意:假设您想匹配' data'PNG 图像(或类似的图像)中的文本,我将您的 == 更改为 =~:

$ file TrueTable-1.png| cut -f2 -d':'
PNG image data, 405 x 292, 8-bit colormap, non-interlaced

如果这个假设不正确,请发表评论。

相关内容