Eu tenho um diretório com subdiretórios. Nos diretórios, há muitas imagens, rastreadas na web.
Como faço para percorrer todos os arquivos e mostrar os arquivos que não são arquivos de imagem válidos?
Não deve ser baseado na extensão do arquivo.
Eu criei 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
Mas isso não está funcionando, porque também gera imagens válidas.
Responder1
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
Minha abordagem usa -exec
para realizar um teste personalizado em arquivos. Uma concha é necessária para construir um tubo. Um shell separado é executado para cada arquivo com a extensão correta, portanto a solução tem um desempenho bastante ruim.
O shell é executado file -b --mime-type
e grep
verifica se o resultado começa com image/
. !
no início do canal nega seu status de saída, portanto, todo o -exec
teste será bem-sucedido se o arquivo não for realmente uma imagem. O caminho é então impresso.
Notas:
- Omita
-name
os testes para verificar todos os arquivos. - Ou você pode querer usar
-iname
em vez de-name
. -iname
não é exigido pelo POSIX. Nem é-b
nem--mime-type
opção defile
.O seguinte produz uma saída ligeiramente diferente e é mais rápida:
find . -type f \ \( -name '*.jpg' -o -name '*.jpeg' -o -name '*.gif' -o -name '*.png' \) \ -exec file --mime-type {} + \ | grep -v "\bimage/"
masalguns nomes de arquivos (por exemplo, com novas linhas) ou caminhos (com
image/
) quebrarão a lógica.
Responder2
Você deve fazer isso verificando as assinaturas do tipo de arquivo. Pode ser encontradoaqui, ou você pode encontrá-lo por tentativa e erro, verificando seus arquivos.
Por exemplo, a assinatura JPG é FF D8 FF E0
, o que significa que seus primeiros quatro bytes devem ser iguais a FF D8 FF E0
.
Tudo que você precisa é de uma ferramenta para combinar esses bytes com os do arquivo. Por exemplo, hexdump -n 4 -C file.jpg| awk '{print $2 $3 $4 $5}'
retorna aqueles bytes em formato hexadecimal, que podem ser comparados com a assinatura desejada.
Se os arquivos de imagem que você possui podem estar corrompidos, informações avançadas sobre assinaturas de arquivos e recuperação podem ser encontradasaqui. Por exemplo, quando apenas uma fração de uma imagem é baixada.
Responder3
A verificação da extensão do arquivo e dos bytes mágicos pode ser facilmente falsificada. Verhttps://unix.stackexchange.com/questions/189364/script-to-determine-if-apparent-image-files-are-real-image-files/189367#189367para se inspirar, basicamente use o imagemagick para verificar se a imagem é válida, mas mesmo assim isso pode ser falsificado! Portanto, não há uma maneira perfeita de verificar.