비지박스 찾기를 사용하여 특정 파일 확장자를 제거(또는 유지)하는 방법은 무엇입니까?

비지박스 찾기를 사용하여 특정 파일 확장자를 제거(또는 유지)하는 방법은 무엇입니까?

파일(다양한 파일 확장자)과 하위 폴더가 포함된 폴더가 있습니다. 특정 파일 확장자를 유지하고 나머지는 제거하고 싶습니다.

e.g. keep all .txt and .jpg files and delete all other files.

일반 UNIX/GNU에서는 이를 달성하기 위해 "-not" 인수와 함께 find를 사용할 수 있습니다.

> find . -not -name "*.jpg" -not -name "*txt" -type f -delete

하지만 불행하게도 이 매개변수는 busybox find에서는 사용할 수 없습니다.

이 작업을 수행하는 방법에 대한 아이디어가 있습니까? 감사합니다

답변1

-not그리고 -delete그것은 비표준 확장입니다.

-not더 짧은 표준과 동등한 것이 있는 경우에는 사용할 이유가 없습니다 !.

의 경우 조건자 호출을 사용해야 -delete합니다 .rm-exec

find . ! -name '*.jpg' ! -name '*.txt' -type f -exec rm -f '{}' +

-exec rm -f '{}' ';'(이전 버전의 busybox를 사용하는 경우 파일당 하나씩 실행 해야 할 수도 있습니다 rm.)

위의 명령은 표준이므로 busybox뿐만 아니라 GNU가 아닌 다른 최신 구현에서도 작동합니다 find.

적어도 GNU 시스템에서는 이 명령( findGNU를 사용하는 모든 구현이 작동함 fnmatch(3))은 이름이 .jpg또는 로 끝나는 일부 파일을 삭제할 수 있습니다. 패턴은 이름에 현재 유효하지 않은 문자가 포함된 파일과 일치할 수 없기 .txt때문입니다. *.jpg장소.

이 문제를 해결하려면 다음을 수행해야 합니다.

LC_ALL=C find . ! -name '*.jpg' ! -name '*.txt' -type f -exec rm -f '{}' +

또한 GNU 와 달리 이 방법은 시스템 호출에 전달된 파일 경로의 최대 크기에 결국 도달하므로 -delete매우 깊은 디렉토리 트리에서는 작동하지 않습니다 . unlink()AFAIK, 구현이 Nor를 지원하지 않으면 find이 문제를 해결할 방법이 없습니다.find-execdir-delete

당신은 또한 읽고 싶을 수도 있습니다GNU 매뉴얼 find에서 논의된 보안 고려 사항다른 사람이 쓸 수 있는 디렉터리에서 명령을 실행하는 경우.

답변2

바쁜 상자find 주장하다-regex파일을 삭제하는 데 사용할 수 있는 옵션 지원일치하다모델:

find . -type f -regex '.*\.tmp\|.*\.core' -delete

안타깝게도 일반적인 경우 -not옵션이 없는 확장 목록을 제외하는 것은 불가능합니다(기술적으로는해결책이 있다단, 연장할 수는 없습니다.) 이것이 바로 -not이 옵션이 처음에 포함된 이유입니다. 임의의 확장 목록을 제외해야 하는 경우 find이 옵션을 지원하는 확장 또는 ++ find가 필요합니다 .grepxargs

find . | grep -v -e '\.jpg$' -e '\.txt$' | xargs rm

관련 정보