我试图在目录结构中查找“损坏”文件,即文件命令将解释为“数据”的文件。这是我一直尝试运行但失败的命令:
$ 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
如果这个假设不正确,请发表评论。