find 명령에서 공백 사용 문제

find 명령에서 공백 사용 문제

하위 디렉터리가 포함되지 않은 각 디렉터리에 해당 디렉터리의 내용이 포함된 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 {} \;

관련 정보