2010-06-04 11 views
6

Ok, tengo un directorio (por ejemplo, llamado '/ photos') en el que hay diferentes directorios (como '/ photos/wedding', '/ photos/birthday', '/ photos/graduation', etc. ..) que tienen archivos .jpg en ellos. Desafortunadamente, algunos de los archivos jpeg están rotos. Necesito encontrar la manera de determinar qué archivos están rotos. Descubrí que hay una herramienta llamada imagemagic, que puede ayudar mucho. Si lo usa así:¿Cómo puedo verificar si todos los archivos dentro de los directorios son jpegs válidos (Linux, se necesita script sh)?

identify -format '%f' whatever.jpg 

se imprime el nombre del archivo sólo si el archivo es válido, si no es que se imprime algo así como "identificar: No es un archivo JPEG: comienza con 0x69 0x75 'lo que sea. jpg '@ jpeg.c/EmitMessage/232. ". Así que la solución correcta debería ser encontrar todos los archivos que terminan en ".jpg", aplicarles "identificar", y si el resultado es solo el nombre del archivo - no haga nada, y si el resultado es diferente del nombre del archivo - luego guarde el nombre del archivo en alguna parte (como en un archivo "errors.txt").

¿Alguna idea de cómo puedo hacer eso?

+0

Relacionado: [¿Hay alguna herramienta para verificar la integridad del archivo de una serie de imágenes?] (Https://photo.stackexchange.com/q/ 46919) – sampablokuper

Respuesta

5

Puede poner esto en archivo de script bash o ejecutar directamente: find |grep ".jpg$" |xargs identify -format '%f' 1>ok.txt 2>errors.txt

+4

También se puede escribir como 'find -name' * .jpg '-exec identify -format "% f" {} \; 1> ok.txt 2> errors.txt'. –

+2

Marcar como aceptado; sin embargo, el script final es: find -name '* .jpg' -exec identify -format "% f \ n" {} \; 2> errors.txt Eso podría ser exactamente lo que necesito, probado en datos de prueba y errors.txt dame toda la información necesaria (ok.txt no me sirve, así que lo eliminé del script). ¡Gracias a todos los que participaron! – Graf

2

Este script imprimir los nombres de los archivos mal:

#!/bin/bash 

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

usted podría funcionar como es o como ./badjpegs > errors.txt a guardar la salida en un archivo.

Para descomponerlo, el comando find encuentra *.jpg archivos en /photos o cualquiera de sus subdirectorios. Estos nombres de archivos se canalizan a un ciclo while, que los lee uno a la vez en la variable $FILE. Dentro del ciclo, tomamos la salida de identify usando el operador $(...) y verificamos si coincide con el nombre del archivo. Si no, el archivo está dañado e imprimimos el nombre del archivo.

Puede ser posible simplificar esto. La mayoría de los comandos de UNIX indican éxito o falla en su código de salida. Si el comando identify hace esto, entonces se podría simplificar el script para:

#!/bin/bash 

find /photos -name '*.jpg' | while read FILE; do 
    if ! identify "$FILE" &> /dev/null; then 
     echo "$FILE" 
    fi 
done 

Aquí la condición se simplifica a if ! identify; then lo que significa "se identificaban a fallar?"

11

Un problema con identify -format es que en realidad no compruebe que el archivo no está dañado, sólo se asegura de que es realmente un archivo JPEG .

Para probarlo realmente necesita algo para convertirlo. Pero el converso que viene con ImageMagick parece ignorar silencio errores no fatales en el jpeg

Una cosa que funciona es la siguiente (como se trunque.):

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

Si se devuelve un error código, el archivo tiene un problema. Si no, está bien.

Hay otros programas que también se pueden usar.

+0

Eso era importante de comentar. La respuesta de Alexx muestra otra herramienta para verificar un archivo JPG: 'jpeginfo -c archivo'. – tokland

+0

Por si acaso, si necesita verificar todos los archivos jpg en la carpeta, haga esto: 'for f in * .jpg; hacer djpeg -fast -grayscale -onepass $ f>/dev/null; hecho' – troyane

6

La corta versión corta:

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

puede que no necesite el mismo encontrar opciones, pero JPEGInfo fue la solución que funcionó para mí:

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

como un script (como se solicita en esta pregunta)

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

Me dieron una pista en jpeginfo para esto por http://www.commandlinefu.com/commands/view/2352/find-corrupted-jpeg-image-files y esto explicó mixing find -o OR with -exec

+0

encontrar. -type f -iname "* .jpg" -exec identify -format '% f' {} \; 1>/dev/null # es más rápido que jpeginfo –

+0

Desafortunadamente 'identify' no se queja de algunos archivos jpg truncados que tengo, pero' jpeginfo -c' sí, entonces recomiendo 'jpeginfo -c' – iheggie

Cuestiones relacionadas