如何检查目录中的所有文件是否都是有效的jpegs(Linux,需要sh脚本)?

时间:2010-06-04 12:58:34

标签: shell image-processing

好的,我有一个目录(例如名为'/ photos'),其中有不同的目录 (如'/ photos / wedding','/ photos / birthday','/ photos / graduation'等...)其中包含.jpg文件。不幸的是,一些jpeg文件被破坏了。我需要找到一种方法来确定哪些文件被破坏了。 我发现,有一个名为imagemagic的工具,可以提供很多帮助。如果您这样使用它:

identify -format '%f' whatever.jpg

只有当文件有效时才打印文件的名称,如果不是,则打印出类似“识别:不是JPEG文件:以0x69 0x75开头`whatever.jpg'@ jpeg.c / EmitMessage / 232。 ”。 因此,正确的解决方案应该是找到以“.jpg”结尾的所有文件,将它们应用于“识别”,如果结果只是文件的名称 - 不要做任何事情,如果结果与名称不同的文件 - 然后保存文件的名称(如文件“errors.txt”)。

任何想法我怎么可能这样做?

4 个答案:

答案 0 :(得分:13)

identify -format的一个问题是它实际上并没有验证文件是否已损坏,只是确保它确实是一个jpeg。

要真正测试它,你需要一些东西来转换它。但是 ImageMagick 附带的转换似乎默默地忽略了jpeg中的非致命错误(例如被截断)。

有一件事是这样的:

djpeg -fast -grayscale -onepass file.jpg > /dev/null

如果它返回错误代码,则该文件有问题。如果没有,这很好。

还可以使用其他程序。

答案 1 :(得分:10)

短短版本:

find . -iname "*.jpg" -exec jpeginfo -c {} \; | grep -E "WARNING|ERROR"

您可能不需要相同的查找选项,但jpeginfo是适用于我的解决方案:

find . -type f -iname "*.jpg" -o -iname "*.jpeg"| xargs jpeginfo -c | grep -E "WARNING|ERROR" | cut -d " " -f 1

作为脚本(按照本问题的要求)

#!/bin/sh
find . -type f \
\( -iname "*.jpg" \
 -o -iname "*.jpeg" \) \
-exec jpeginfo -c {} \; | \
grep -E "WARNING|ERROR" | \
cut -d " " -f 1

我在http://www.commandlinefu.com/commands/view/2352/find-corrupted-jpeg-image-files找到了jpeginfo,这解释了mixing find -o OR with -exec

答案 2 :(得分:7)

您可以将其放入bash脚本文件中或直接运行:

find -name "*.jpg" -type f |xargs --no-run-if-empty identify -format '%f' 1>ok.txt 2>errors.txt

如果缺少identify,以下是如何在Ubuntu中安装它:   sudo apt install imagemagick --no-install-recommended

答案 3 :(得分:2)

此脚本将打印出坏文件的名称:

#!/bin/bash

find /photos -name '*.jpg' | while read FILE; do
    if [[ $(identify -format '%f' "$FILE" 2>/dev/null) != $FILE ]]; then
        echo "$FILE"
    fi
done

您可以按原样或./badjpegs > errors.txt运行它以将输出保存到文件中。

要对其进行细分,find命令会在*.jpg或其任何子目录中找到/photos个文件。这些文件名通过管道传输到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 ! identify; then,这意味着“确实失败了吗?”