在 OS X 10.8 中,我有几个包含图片的文件夹,但并非所有文件都有正确的扩展名,有些 GIF 被命名为 JPG 等等。
我有一个可以完成实际目录工作的单行程序:
for f in * ; do type=$(file "$f" | tr "[A-Z]" "[a-z]" | awk '{print $2}') ; mv "$f" "${f%.*}.$type" ; done
现在我想使用“查找”来搜索子文件夹但总是失败。
有什么提示吗?
答案1
在这种情况下,您可以轻松找到与扩展名 .jpg 不匹配的文件:
find . -type f -not "*.jpg"
您还可以循环检查结果并检查文件是否确实是 jpg:
find . -type f -not "*.jpg" | while read fname; do
if [[ $(file $fname) == *"JPG"*]]
then echo $fname
fi
done
答案2
最简单的方法是启用文件的递归通配符,例如在 Bash 中:
shopt -s globstar
for f in **/*.*; do
type=$(file "$f" | tr "[A-Z]" "[a-z]" | awk '{print $2}')
mv -- "$f" "${f%.*}.$type"
done
这样就不必解析find
输出。问题是,如果文件太多,此命令可能会失败,因为它可能超出命令行的最大大小。这是因为**/*.*
在执行命令之前,Bash 会扩展 中的文件名。
因此,另一种方法是使用find
,将其输出通过管道传输到while
和read
。
find . -type f -print0 | while IFS= read -r -d '' f
type=$(file "$f" | tr "[A-Z]" "[a-z]" | awk '{print $2}')
mv -- "$f" "${f%.*}.$type"
done
有关使用文件列表的一些最佳实践,请参阅:http://mywiki.wooledge.org/ParsingLs
答案3
我发现这种方法对我来说很有效,但它并不是很优雅:-P
find . -type f -name "*.*" -exec sh -c 'name=$(basename {} | cut -d. -f1) ; type=$(file {} | tr "[A-Z]" "[a-z]" | cut -d" " -f2) ; mv `basename {}` "$name.$type"' \;
答案4
根据前面的评论,我猜您正在寻找一种不循环遍历结果的方式来解析结果,只需使用 find:
find . -type f -not "*.jpg" -exec sh -c "if [[ $(file {}) == *'JPG'* ]] then; echo {}; fi" \;