Shell 如何检查目录中的所有文件是否都是有效的JPEG(需要Linux、sh脚本)?
好的,我得到了一个目录(例如,名为“/photos”),其中有不同的目录 (如“/photos/wedding”、““/photos/birth”、““/photos/discalation”等),其中包含.jpg文件。不幸的是,一些jpeg文件已损坏。我需要找到一种方法来确定哪些文件被破坏了。 我发现,有一个叫做imagemagic的工具,它可以帮助很多人。如果您这样使用它:Shell 如何检查目录中的所有文件是否都是有效的JPEG(需要Linux、sh脚本)?,shell,image-processing,Shell,Image Processing,好的,我得到了一个目录(例如,名为“/photos”),其中有不同的目录 (如“/photos/wedding”、““/photos/birth”、““/photos/discalation”等),其中包含.jpg文件。不幸的是,一些jpeg文件已损坏。我需要找到一种方法来确定哪些文件被破坏了。 我发现,有一个叫做imagemagic的工具,它可以帮助很多人。如果您这样使用它: identify -format '%f' whatever.jpg 它仅在文件有效时打印文件名,如果文件无效,则打
identify -format '%f' whatever.jpg
它仅在文件有效时打印文件名,如果文件无效,则打印类似“标识:非JPEG文件:以0x69 0x75`whatever.jpg'@JPEG.c/EmitMessage/232开头”的内容。
因此,正确的解决方案应该是找到以“.jpg”结尾的所有文件,并对其应用“标识”,如果结果只是文件名-不要做任何事情,如果结果与文件名不同-则将文件名保存在某个位置(如文件“errors.txt”)
你知道我该怎么做吗?此脚本将打印出坏文件的名称:
#!/bin/bash
find /photos -name '*.jpg' | while read FILE; do
if [[ $(identify -format '%f' "$FILE" 2>/dev/null) != $FILE ]]; then
echo "$FILE"
fi
done
您可以按原样运行它,也可以按/badjpeg>errors.txt
将输出保存到文件中
要将其分解,请使用find
命令在/photos
或其任何子目录中查找*.jpg
文件。这些文件名通过管道传输到while循环,该循环一次读取一个文件名到变量$file
。在循环内部,我们使用$(…)
操作符获取identify
的输出,并检查它是否与文件名匹配。如果不是,则文件是坏的,我们打印文件名
这也许可以简化。大多数UNIX命令在其退出代码中表示成功或失败。如果identify
命令执行此操作,则可以将脚本简化为:
#!/bin/bash
find /photos -name '*.jpg' | while read FILE; do
if ! identify "$FILE" &> /dev/null; then
echo "$FILE"
fi
done
此处条件简化为
if!识别然后
,意思是“标识失败了吗?”您可以将其放入bash脚本文件或直接运行:
find-name“*.jpg”-键入f|xargs--如果标识为空则不运行-格式“%f”1>ok.txt 2>errors.txt
如果缺少identify
,以下是如何在Ubuntu中安装它:
sudo apt install imagemagick--无安装建议标识格式的一个问题是,它实际上并没有验证文件是否损坏,只是确保它确实是一个jpeg 要实际测试它,您需要一些东西来转换它。但是ImageMagick附带的转换似乎默默地忽略了jpeg中的非致命错误(例如被截断) 有效的一点是:
djpeg -fast -grayscale -onepass file.jpg > /dev/null
如果返回错误代码,则文件有问题。如果没有,那就好了
也可以使用其他程序。简短版本:
find-iname“*.jpg”-execjpeginfo-c{}\|grep-E“警告|错误”
您可能不需要相同的查找选项,但jpeginfo是适合我的解决方案:
find-键入f-iname“*.jpg”-o-iname“*.jpeg”| xargs jpeginfo-c | grep-E“警告|错误”| cut-d“-f 1
作为脚本(根据本问题的要求)
我是通过jpeginfo了解到这一点的,并解释了这一点也可以写成
find-name'*.jpg'-exec-identify-format“%f”{};1> ok.txt 2>errors.txt
。将其标记为已接受,但是,最后的脚本是:find-name'*.jpg'-exec-identify-format“%f\n”{};2> errors.txt这可能正是我需要的,测试数据和errors.txt给我所有必要的信息(ok.txt对我没有好处,所以我从脚本中删除了它)。感谢所有参与的人!答案中给出的命令给了我一个错误xargs:identify:没有这样的文件或directory@Graf谢谢你注意到这一点。伦敦人:首先检查是否安装了identify。@alexx roche下面的答案与查找更相关(检测部分JPEG)-键入f-iname“*.jpg”-exec-identify-格式“%f”{}\;1> /dev/null#比jpeginfo更快不幸的是identify
并没有抱怨我有一些被截断的jpg文件,但是jpeginfo-c
有,所以我建议大家注意一下jpeginfo-c
。Alexx的回答显示了另一个检查JPG文件的工具:jpeginfo-c文件
。以防万一,如果您需要检查文件夹中的所有JPG文件,请执行以下操作--检查*.JPG中的f;dodjpeg-fast-grayscale-onepass$f>/dev/null;完成
相关:
#!/bin/sh
find . -type f \
\( -iname "*.jpg" \
-o -iname "*.jpeg" \) \
-exec jpeginfo -c {} \; | \
grep -E "WARNING|ERROR" | \
cut -d " " -f 1