xargs 및 rm + 파일 이름에 공백이 포함되어 있습니다.

xargs 및 rm + 파일 이름에 공백이 포함되어 있습니다.

저는 획득한 모든 파일을 삭제하는 간단한 프로그램을 작성하고 있습니다. 파일에 공백이 포함될 수 있으므로 아래와 같이 따옴표를 추가했습니다.

find -name "*.scala" | xargs -d "\n" -I {} rm \"{}\"

다음 오류로 인해 위 작업이 실패합니다. 삭제할 수 없습니다. 해당 파일이나 디렉터리가 없습니다. 하지만 동일한 파일을 나열하면 해당 파일이 거기에 있습니다. 또한 다음을 수행하고 bash를 사용하여 실행하면 작동합니다.

find -name "*.scala" | xargs -d "\n" -I {} echo rm \"{}\" | bash

누군가 첫 번째 사례가 작동하지 않는 이유를 설명할 수 있습니까?

답변1

xargs -d "\n" -I {} rm \"{}\"

이는 GNU coreutils 버전이 구분 기호를 지정하는 옵션을 xargs지원한다고 가정합니다.-d

find에서 찾은 경로 이름에 큰따옴표를 추가하기 때문에 명령 에서는 작동하지 않습니다 find. 이는 에 대한 호출이 리터럴 경로명을 통해 수행 ./somedir/file.scala되지 않음 을 의미합니다 .rm"./somedir/file.scala"

예:

$ touch hello
$ touch '"hello"'
$ ls
"hello" hello
$ echo hello | xargs -d "\n" -I {} rm \"{}\"
$ ls
hello

따옴표가 제거되므로 bash생성 된 명령을 파이프할 때 작동합니다 .bash

따옴표를 먼저 추가하기 위해 추가 노력을 기울이지 않는 경우에도 작동할 수 있습니다.

xargs -d "\n" -I {} rm {}

파일을 올바르게 삭제하려면 다음을 사용하십시오.

find . -type f -name '*.scala' -delete

또는 여전히 사용하고 싶은 경우 xargs:

find . -type f -name '*.scala' -print0 | xargs -0 rm

findxargs와 사이의 경로 이름을 빈 구분 목록으로 전달합니다 . 비어 있음( \0)은오직Unix 시스템에서는 경로 이름에 문자가 허용되지 않습니다. 또한 파일 이름에는 가 포함될 수 없지만 /개행 문자는 허용됩니다.

세 번째 옵션은 rm다음에서 직접 전화하는 것 입니다 find.

find . -type f -name '*.scala' -exec rm {} +

공백(또는 줄 바꿈 등)이 포함된 경로 이름을 명명 유틸리티에 전달하는 방법이 완벽하게 명확하므로 인용 은 {}필요하지 않으며 필요하지도 않습니다 .find

관련 정보