파일 대량 삭제

파일 대량 삭제

디렉토리와 하위 디렉토리의 모든 txt, xls,pdf 파일을 삭제하고 싶습니다. 다른 모든 것을 저장하고 싶습니다.

find . -type f ! -iname '*.xml$,.png$,.jpeg$,.gif$,' -delete

그렇게 한 것 같았는데 필요한 다른 파일이 삭제되었습니다. 다른 것을 삭제하지 않고 어떻게 이를 달성할 수 있습니까?

답변1

대신 이렇게 하세요:

find . -type f -iname '*.xml' -o -iname '*.png'\
       -o -iname '*.jpeg' -o -iname '*.gif' -delete

정규식을 사용할 수도 있습니다.

find . -type f -iregex '.*\.\(xml\|png\|jpeg\|gif\)$' -delete

답변2

find를 사용하여 이 문제에 접근하는 방법에는 기본적으로 4가지가 있습니다.

방법 #1 - 사용-delete

$ find . -type f -iname '*.xml' -o -iname '*.png'\
       -o -iname '*.jpeg' -o -iname '*.gif' -delete

이 Q&A에서 다른 사람들이 언급했듯이 이 방법은 가장 빠르고 리소스를 덜 소모합니다. 에서 인용온라인 문서 찾기:

10.1.6 `-delete' 작업 사용


이 문제를 해결하는 가장 효율적이고 안전한 방법은 `-delete' 동작을 사용하는 것입니다:

 find /var/tmp/stuff -mtime +90 -delete

-exec' or이 대안 은 새 프로세스를 분기하고 exec' to run/bin/rm'을 사용하는 오버헤드를 완전히 피하기 때문에 -execdir' 작업 보다 더 효율적입니다 . 또한 이는 일반적으로 xargs' for the same reason. The file deletion is performed from the directory containing the entry to be deleted, so the-delete' 조치보다 더 효율적이며 `-execdir' 조치와 동일한 보안 이점을 갖습니다.

`-delete' 동작은 BSD 운영 체제 제품군에 의해 도입되었습니다.

메모:이 접근 방식에서 명심해야 할 한 가지는 의 사용은 -delete스위치도 의미한다는 것입니다 -depth. 이것은 무엇을 의미 하는가? -delete조심하지 않으면 어떻게 화상을 입을 수 있는지에 대한 예는 다음과 같습니다 .

예를 들어, 일부 파일을 정리하고 .svn 하위 디렉터리는 그대로 두려는 Subversion 작업 디렉터리가 있다고 가정해 보겠습니다. 이를 수행하려면 다음 명령을 사용할 수 있습니다.

$ find . -not "(" -name .svn -type d -prune ")" -type f -print
./a.txt

그러나 스위치가 -delete포함되어 있으므로 -depth실제로 처리되는 파일은 다음과 같습니다.

$ find . -not "(" -name .svn -type d -prune ")" -type f -print -depth
./.svn/all-wcprops
./.svn/entries
./.svn/format
./.svn/text-base/a.txt.svn-base
./a.txt

때문에 사용시에는 -delete주의가 필요합니다.

방법 #2 --exec command {} +

$ find . -type f -iname '*.xml' -o -iname '*.png'\
       -o -iname '*.jpeg' -o -iname '*.gif' -exec rm {} \+

이 방법과 비교할 때 -delete이는 Unix 전반의 성능 및 이식성 측면에서 차선책일 가능성이 높습니다. 표기법 -exec ... {} +은 다음과 같이 작동합니다.

맨 페이지 찾기에서

-exec 작업의 이 변형은 선택한 파일에 대해 지정된 명령을 실행하지만 명령줄은 선택한 각 파일 이름을 끝에 추가하여 작성됩니다. 명령의 총 호출 수는 일치하는 파일 수보다 훨씬 적습니다. 명령줄은 xargs가 명령줄을 작성하는 것과 거의 동일한 방식으로 작성됩니다. 명령 내에서는 `{}' 인스턴스가 하나만 허용됩니다. 명령은 시작 디렉터리에서 실행됩니다.

따라서 실제로 이 방법은 와 유사하게 작동 xargs하지만 find의 출력을 파이프를 통해 로 전달하는 과정을 거치지 않아도 됩니다 xargs.

방법 #3 -xargs

$ find . -type f -iname '*.xml' -o -iname '*.png'\
       -o -iname '*.jpeg' -o -iname '*.gif' -print0 | xargs -0 rm -f

find ... -print0지정된 기준과 일치하는 파일 목록이 작성됩니다 . 그런 다음 이 목록은 파이프를 통해 xargs. 스위치 -print0는 find의 각 결과 사이에 구분 기호로 ASCII NUL 문자를 넣습니다. 스위치 -0를 켜면 xargs전달되는 파일이 ASCII NUL 문자로 구분되어 있다고 가정합니다.

방법 #1 및 #2와 비교하면 이 방법은 #2와 비슷한 성능을 가지지만 스위치 -print0가 모든 Unix에서 보편적으로 지원되는 것은 아닙니다.

방법 #4 --exec command {} \;

$ find . -type f -iname '*.xml' -o -iname '*.png'\
       -o -iname '*.jpeg' -o -iname '*.gif' | exec rm -f {} \;

처음 3가지 방법에 비해 성능이 가장 낮습니다. 문자 그대로 명령이 찾은 rm각 개별 파일에 대해 명령을 호출합니다 find.

보안에 대한 추가 고려사항

위의 방법 중 하나를 사용할 때 그다지 명확하지 않을 수 있는 한 가지는 일부 방법이 다른 방법보다 더 안전하다는 것입니다. 아마도 당신은 스스로에게 이렇게 말하고 있을 것입니다. 보안? .. 무엇? 여기에 예가 있습니다.

루트를 가정하고 다음 명령을 실행합니다.

$ find /var/tmp/somedir -type f -exec rm {} \;

/etc당신도 모르는 사이에 누군가가 악의적으로 아래 디렉토리 에 대한 링크를 생성했습니다 /var/tmp/somedir. 위의 명령이 실행되면 디렉터리 /etc도 삭제됩니다. 이 문제는 -delete옵션(방법 #1) 을 제외한 모든 파일 삭제 방법에서 발생합니다 .

tl;dr;

find를 사용하여 파일을 삭제하는 가장 빠르고 안전한 방법은 -delete. 을 사용하면 xargs -0성능이 비슷할 수 있지만 그만큼 안전하지는 않습니다. 작업 -delete은 완전히 이식 가능하지 않습니다. 가장 효율적인 이식 가능한 대안은 이지만 -exec ... +이는 안전하지 않으며 4.2.12 이전의 GNU findutils 버전에서는 지원되지 않습니다.

참고자료

답변3

약간의 부정확성이 있습니다슬름 답변.

참고 및 면책조항: 이것은 다음에 대한 주석이어야 합니다.슬름 답변하지만 지금은 아직 댓글을 달 수 없습니다.

"누군가 악의적으로 링크를 생성했습니다"라는 예는 다음과 같습니다.보안에 대한 추가 고려사항Unix 하드 링크와 Unix 소프트 링크 모두에 대해 완전히 정확하지는 않습니다.

둘의 차이점을 이해하려면 다음을 참조하세요.Unix의 하드링크와 심볼릭링크아니면 구글에 검색해 보세요.

소프트 링크(어쨌든 가장 많이 사용되는 유형)의 경우 GNU findBDS find 하지 않습니다심볼릭 링크를 따르도록 강제하기 위해 특정 -L플래그를 사용하지 않는 한 심볼릭 링크를 따릅니다. [보다 man find]

따라서 이 예는 문제가 되지 않을 것입니다. find플래그 를 사용하여 소프트 링크를 따라갑니다 -L. 어쨌든 이것은 위험한 선택이다.

하드 링크의 경우 find다음 링크를 따르세요.다른 파일하지만 하드 링크는다른 디렉토리man lnGNU에 대한 설명처럼 "아마도 실패할 것입니다" ln:

   -d, -F, --directory
          allow the superuser to attempt to hard link directories (note: will probably
          fail due to system restrictions, even for the superuser)

따라서 처음부터 디렉토리에 대한 하드 링크를 생성하는 것은 불가능할 것이며 find따라갈 것도 없을 것입니다.

일부 BDS 구현에는 옵션이 전혀 ln없습니다 .-d

관련 정보