-delete를 사용하면 내 /save/ 디렉토리에서 파일을 삭제할 수 있지만 삭제 없이는 찾을 수 없는 이유는 무엇입니까?

-delete를 사용하면 내 /save/ 디렉토리에서 파일을 삭제할 수 있지만 삭제 없이는 찾을 수 없는 이유는 무엇입니까?

을 제외한 현재 디렉터리 트리의 모든 파일을 삭제하고 싶습니다 save. 다음 명령을 실행했습니다.

 find . \( -name save -prune \) -o -type f -ls | grep /save/

아무것도 발견되지 않았습니다. 하지만 이 명령을 실행하면:

 find . \( -name save -prune \) -o -type f -delete

/save/에 있는 모든 파일이 사라졌습니다. 내가 무엇을 놓치고 있나요?

답변1

-delete-depth적용할 수 없음을 의미합니다 -prune( -depth잎으로 시작). GNU 버전 매뉴얼에 이에 대한 경고가 있습니다(이것은 이제 GNU 및 일부 다른 구현에서도 지원되는 FreeBSD 확장입니다 -delete).find

info -- find -delete

명령줄에서 "-삭제" 작업을 사용하면 "-깊이" 옵션이 자동으로 켜집니다(*검색 표현식 참고::). 이전에 테스트를 위해 "-print"를 사용한 적이 있다면 이는 놀랄 수 있으므로 일반적으로 "-깊이"를 명시적으로 사용하는 것을 기억하는 것이 가장 좋습니다.

info -- find -prune

"-delete"는 "-깊이"를 의미하므로 "-prune"을 "-delete"와 함께 사용하면 예상보다 더 많은 파일이 삭제될 가능성이 높습니다.

여기에서 다음을 사용하도록 선택할 수 있습니다 rm.

find . -name save -prune -o -type f -exec rm -f {} +

(가능한안전하지 않음다른 사람이 쓸 수 있는 디렉토리가 있는 경우 명령을 실행할 때 디렉토리를 심볼릭 링크로 바꾸면 현재 디렉토리 트리 외부의 파일을 삭제할 수 있기 때문입니다.

더 안전한 대안:

find . -name save -prune -o -type f -execdir rm -f -- {} \;

위에서 언급한 문제는 없지만 rm파일당 하나씩 실행한다는 의미입니다. 이는 --GNU 구현이 아닌 FreeBSD 구현에서 필요합니다 ./.

또는 Costas가 제안한 것처럼:

LC_ALL=C find . ! -name save ! -path '*/save/*' -type f -delete

(그러나 이것은 여전히 ​​불필요하게 디렉토리를 삭제합니다 save)

따라서 모든 바이트 시퀀스 LC_ALL=C*일치합니다(현재 로케일에서 유효한 문자를 형성하지 않는 바이트도 포함). 이는 오류 메시지의 언어(사용자 언어가 아닌 영어)에 영향을 미칩니다.

관련 정보