을 제외한 현재 디렉터리 트리의 모든 파일을 삭제하고 싶습니다 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
와 *
일치합니다(현재 로케일에서 유효한 문자를 형성하지 않는 바이트도 포함). 이는 오류 메시지의 언어(사용자 언어가 아닌 영어)에 영향을 미칩니다.