Tengo un directorio con subdirectorios. En los directorios hay muchas imágenes, rastreadas desde la web.
¿Cómo puedo recorrer cada archivo y mostrar aquellos archivos que no son archivos de imagen válidos?
No debe basarse en la extensión del archivo.
Se me ocurrió este script:
find . -name '*.jpg' -o -name '*.jpeg' -o -name '*.gif' -o -name '*.png' | while read FILE; do
if ! identify "$FILE" &> /dev/null; then
echo "$FILE"
fi
done
Pero esto no funciona porque también genera imágenes válidas.
Respuesta1
find . -type f \
\( -name '*.jpg' -o -name '*.jpeg' -o -name '*.gif' -o -name '*.png' \) \
-exec sh -c '! file -b --mime-type "$1" | grep -q "^image/"' sh {} \; \
-print
Mi enfoque utiliza -exec
realizar una prueba personalizada en archivos. Se necesita un caparazón para construir una tubería. Se ejecuta un shell independiente para cada archivo con la extensión correcta, por lo que la solución funciona bastante mal.
El shell se ejecuta file -b --mime-type
y luego grep
comprueba si el resultado comienza con image/
. !
al comienzo de la tubería niega su estado de salida, por lo que toda la -exec
prueba tiene éxito si el archivo no es realmente una imagen. Luego se imprime la ruta.
Notas:
- Omita
-name
las pruebas para comprobar todos los archivos. - O tal vez quieras utilizarlo
-iname
en lugar de-name
. -iname
Sin embargo, POSIX no lo requiere. Ni lo es-b
ni--mime-type
opción defile
.Lo siguiente produce un resultado ligeramente diferente y es más rápido:
find . -type f \ \( -name '*.jpg' -o -name '*.jpeg' -o -name '*.gif' -o -name '*.png' \) \ -exec file --mime-type {} + \ | grep -v "\bimage/"
peroalgunos nombres de archivos (por ejemplo, con nuevas líneas) o rutas (con
image/
) romperán la lógica.
Respuesta2
Debe hacer esto verificando las firmas del tipo de archivo. se puede encontraraquí, o puede encontrarlo mediante prueba y error revisando sus archivos.
Por ejemplo, la firma JPG es FF D8 FF E0
, lo que significa que sus primeros cuatro bytes deben ser iguales a FF D8 FF E0
.
Todo lo que necesitas es una herramienta para hacer coincidir estos bytes con los del archivo. A modo de ejemplo, hexdump -n 4 -C file.jpg| awk '{print $2 $3 $4 $5}'
devuelve aquellos bytes en formato hexadecimal, que se pueden comparar con la firma deseada.
Si los archivos de imagen que tiene pueden estar dañados, puede encontrar información avanzada sobre firmas de archivos y recuperación.aquí. Por ejemplo, cuando solo se descarga una fracción de una imagen.
Respuesta3
La verificación de la extensión del archivo y los bytes mágicos se puede falsificar fácilmente. Verhttps://unix.stackexchange.com/questions/189364/script-to-determine-if-apparent-image-files-are-real-image-files/189367#189367Para inspirarte, básicamente usa imagemagick para verificar si la imagen es válida, ¡pero incluso entonces eso puede ser falsificado! Así que no hay una forma perfecta de comprobarlo.