하위 디렉터리가 포함되지 않은 각 디렉터리에 해당 디렉터리의 내용이 포함된 zip 파일을 배치하려고 합니다.
다음 명령은 디렉터리 이름 및/또는 파일 이름에 공백이 없으면 작동하지만 공백이 있으면 실패합니다.
find pictures/ -type d -links 2 -execdir sh -c "pwd; echo '{}'; zip -v '{}/{}.zip' '{}/*' -x \*.zip -x \*.id" \;
평소처럼 "{}"를 인용했기 때문에 왜 실패하는지 이해가 되지 않습니다. "{}"도 시도했습니다. 즉, A/B/C/*의 내용을 이용하여 A/B/C/C.zip을 생성해야 합니다. "C"에 공백이 있으면 다음과 같은 결과를 얻습니다.
zip warning: name not matched: ./C/*
zip error: Nothing to do! (./C/./C.zip)
답변1
귀하의 버전에서는 find
문자열 {}
의 가 파일 이름으로 대체됩니다. 문자열의 일부로 사용되면 {}
파일 이름이 삽입되는 방식이므로 거의 항상 오류가 발생합니다. 여기서 파일 이름은 쉘 스크립트 조각으로 사용됩니다. 이름이 지정된 디렉토리가 있으면 a'$(touch wibble)'
명령이 쉘 코드를 실행합니다.
pwd; echo 'a'$(touch wibble)''; zip -v 'a'$(touch wibble)'/a'$(touch wibble)'.zip' 'a'$(touch wibble)'/*' -x \*.zip -x \*.id"`
명령이 어떻게 실행되는지 확인하세요 touch wibble
(4번).
파일 이름을 셸 조각에 대한 인수로 전달해야 합니다. 이는 쉘을 안정적으로 사용 find -exec
하거나 호출하는 유일한 방법입니다 (파일 이름이 공백을 포함한 특수 문자로 제한되지 않는 한). find -execdir
그 다음의 첫 번째 매개변수 sh -c SCRIPT
는 스크립트에서 "$0"
.
또한 zip
압축할 파일 목록에는 와일드카드가 허용되지 않으므로 셸에서 확장하려면 와일드카드를 인용 해제해야 합니다.
find pictures/ -type d -links 2 -execdir sh -c 'pwd; echo "$0"; zip -v "$0/$0.zip" "$0/"* -x \*.zip -x \*.id' {} \;
답변2
다음과 같이 변경하세요.
find pictures -type d -links 2 -execdir \
sh -c 'pwd; echo "$1"; zip -vr "$1/$1.zip" "$1" -x \*.zip -x \*.id' sh {} \;