하위 디렉터리가 있는 디렉터리가 있습니다. 디렉토리에는 웹에서 크롤링된 많은 이미지가 있습니다.
모든 파일을 반복하여 유효한 이미지 파일이 아닌 파일을 표시하려면 어떻게 해야 합니까?
파일 확장자를 기반으로 해서는 안 됩니다.
나는 이 스크립트를 생각해 냈습니다.
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
그러나 이것은 유효한 이미지도 출력하기 때문에 작동하지 않습니다.
답변1
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
내 접근 방식은 -exec
파일에 대한 사용자 지정 테스트를 수행하는 데 사용됩니다. 파이프를 구성하려면 쉘이 필요합니다. 올바른 확장자를 가진 모든 파일에 대해 별도의 셸이 실행되므로 솔루션 성능이 다소 저하됩니다.
쉘이 실행된 file -b --mime-type
다음 grep
결과가 로 시작하는지 확인합니다 image/
. !
파이프 시작 부분에서 종료 상태가 무효화되므로 -exec
파일이 실제로 이미지가 아닌 경우 전체 테스트가 성공합니다. 그러면 경로가 인쇄됩니다.
노트:
-name
모든 파일을 확인하려면 테스트를 생략하세요 .-iname
아니면 대신에 사용할 수도 있습니다-name
.-iname
POSIX에서는 필요하지 않습니다. 의 옵션-b
도 아니며--mime-type
의 옵션도 아닙니다file
.다음은 약간 다른 출력을 생성하며 더 빠릅니다.
find . -type f \ \( -name '*.jpg' -o -name '*.jpeg' -o -name '*.gif' -o -name '*.png' \) \ -exec file --mime-type {} + \ | grep -v "\bimage/"
하지만일부 파일 이름(예: 개행 포함) 또는 경로( 포함
image/
)는 논리를 깨뜨립니다.
답변2
파일 형식 서명을 확인하여 이를 수행해야 합니다. 찾을 수 있습니다여기, 또는 파일을 확인하면서 시행착오를 거쳐 찾을 수 있습니다.
예를 들어 JPG 서명은 입니다 FF D8 FF E0
. 이는 처음 4바이트가 와 같아야 함을 의미합니다 FF D8 FF E0
.
필요한 것은 이러한 바이트를 파일의 바이트와 일치시키는 도구뿐입니다. 예를 들어, hexdump -n 4 -C file.jpg| awk '{print $2 $3 $4 $5}'
원하는 서명과 비교할 수 있는 16진수 형식으로 해당 바이트를 반환합니다.
가지고 있는 이미지 파일이 손상된 경우 파일 서명 및 복구에 대한 고급 정보를 찾을 수 있습니다.여기. 예를 들어 이미지의 일부만 다운로드되는 경우입니다.
답변3
파일 확장자와 매직 바이트 확인은 쉽게 스푸핑될 수 있습니다. 보다https://unix.stackexchange.com/questions/189364/script-to-determine-if-apparent-image-files-are-real-image-files/189367#189367영감을 얻으려면 기본적으로 imagemagick을 사용하여 이미지가 유효한지 확인하세요. 하지만 그래도 스푸핑될 수 있습니다! 따라서 완벽한 확인 방법은 없습니다.