(png|gif|jpe?g)
지정된 필터 (! 공백이 있는 파일 이름 문제를 방지하려면 구분 기호 사용 ) 가 있는 지정된 디렉터리의 모든 파일에 대해 "최적화된" 파일이 있는지 \0
확인하고 싶습니다.webp
아니요, 변환하세요.
나는 다음 내용이 최적화될 수 있다는 것을 알고 있지만 그것이 작동하기를 원합니다.
더 나은 솔루션이 있는 경우(설명이 있습니다!) 물론 재미있기도 하죠.
IFS= readarray -t -d '' tab < <(find . -type f -print0 | grep -zZE "(png|gif|jpe?g)$") && for f in "${tab[@]}"; do if [ ! -f "$f.webp" ]; then cwebp -q 80 "$f" -o "$f.webp"; fi done
이것이 내가 하고 있는 일입니다. readarray
내 패턴과 일치하는 발견된 모든 파일로부터 배열을 생성하고 있습니다. 그런 다음 반복하여 파일이 존재하는지 테스트합니다. 그렇지 않은 경우 cwebp -q 80 "$f" -o "$f.webp";
This one not work를 호출 하고 다음 오류가 발생합니다. 왜?
Error! Could not process file ./08/10700_header.jpg
Error! Cannot read input picture file './08/10700_header.jpg'
Error! Could not process file ./08/205790_header.jpg
Error! Cannot read input picture file './08/205790_header.jpg'
답변1
Bash의 더 나은 솔루션: 실제로 다음을 찾을 필요는 없습니다.
shopt -s extglob # extended pattern match, you likely already have it set
shopt -s globstar # extended directory level search ('**' matches any directory level)
for f in **/*.@(jpg|jpeg|png|gif)
do
[[ -f "$f.webp" ]] || cwebp -q 80 "$f" -o "$f.webp"
done
실행하려면 parallel
이미 완료된 파일을 삭제해야 cwebp
직접 호출할 수 있습니다. 한 가지 방법은 webp 파일 목록을 사용하여 파일 목록을 필터링하는 것입니다.
printf '%s\n' **/*.@(jpg|jpeg|png|gif) \
| grep -vf <(printf '%s\n' **/*.webp | sed 's/\.webp$//') \
| parallel -i cwebp -q 80 {} -o {}.webp
느린:
printf '%s\n' **/*.@(jpg|jpeg|png|gif)
가능한 모든 후보 목록을 스트림으로 생성합니다(이것은printf
내장이므로 bash에서는 명령줄에 바인딩되지 않습니다).grep -vf <(printf '%s\n' **/*.webp | sed 's/\.webp$//')
이 목록에서 모든 관련 파일을 제거합니다.webp
(파일을 나열하고*.webp
확장자를 자르고 결과를grep
패턴 목록으로 사용).parallel -i cwebp -q 80 {} -o {}.webp
결과를 병렬 실행에 제공합니다.
parallel
null로 끝나는 입력을 허용하는 매개변수가 없는 것 같으 므로 이상한 파일 이름이 없기를 바라기만 하면 됩니다.
사전 필터링 기술은 비병렬 상황에서도 사용할 수 있습니다.
답변2
귀하가 표시한 오류가 무엇이고 그 이유가 무엇인지는 확실하지 않지만 아마도 cwebp
귀하가 제공한 경로 이름을 찾는 데 문제가 있는 것 같습니다.
임시 배열을 find
사용하는 대신 관련 파일을 찾고 루프를 수행 하도록 합니다 .grep
find . \( -name '*.png' -o -name '*.gif' -o -name '*.jpg' -o -name '*.jpeg' \) \
-type f -exec sh -c '
for pathname do
[ -f "$pathname.webp" ] && continue
cwebp -q 80 "$pathname" -o "$pathname.webp"
done' sh {} +
find
여기에서는 이를 인라인 스크립트용 경로 이름 생성기 로 사용하고 있습니다 sh -c
. 인라인 스크립트는 경로 이름을 일괄적으로 가져와 이를 반복합니다. 주어진 각 경로 이름에 대해 해당 .webp
파일이 존재하면 루프는 다음 경로 이름으로 점프합니다. 그렇지 않으면 cwebp
명령이 호출됩니다.
이는 이상한 파일이나 디렉토리 이름으로 인한 문제를 방지하고 설치된 모든 cwebp
시스템에 이식 가능합니다( find
명령 자체는 인라인 스크립트와 마찬가지로 표준입니다).
여러분도 구경해 보세요”"find"의 -exec 옵션 이해" -exec sh -c '...' sh {} +
구문에 대한 추가 정보.
그래도 문제가 해결되지 않으면 보고된 이미지 파일을 조사하여 실제로 유효한 이미지 파일인지 확인할 수 있습니다.