디렉토리 및 하위 디렉토리에 있는 모든 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
이 대안은 새 프로세스를 포크하고 /bin/rm'을 사용하는 오버헤드를 완전히 피하기 때문에 어떤 -execdir' 작업보다 더 효율적입니다 .exec' to run
또한 일반적으로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 시리즈 운영 체제에서 도입되었습니다.
노트:이 접근 방식에서 기억해야 할 한 가지는 use 가 -delete
switch 를 의미하기도 한다는 것입니다 -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
스위치는 각 찾기 결과 사이에 구분 기호로 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)을 제외한 모든 파일 삭제 방법에서 발생합니다 .
너무 길어요 박사님;
파일을 삭제하는 가장 빠르고 안전한 방법은 find 를 사용하는 것입니다 -delete
. xargs -0
성능은 비슷할 수 있지만 보안은 낮습니다. 작업 -delete
은 완전히 이식 가능하지 않습니다. 가장 효율적인 이식 가능한 대안은 이지만 -exec ... +
이는 안전하지 않으며 4.2.12 이전의 GNU findutils 버전에서는 지원되지 않습니다.
인용하다
답변3
약간 부정확함슬름 답변.
참고사항 및 면책조항: 댓글이어야 합니다.슬름 답변하지만 아직 댓글을 달 수는 없습니다.
예 "누군가 악의적으로 링크를 생성했습니다."보안에 대한 추가 참고사항Unix 하드 링크나 Unix 소프트 링크 모두 완전히 정확하지는 않습니다.
둘 사이의 차이점을 이해하려면 다음을 참조하세요.Unix의 하드링크와 심볼릭링크아니면 구글에서 검색해보세요.
소프트 링크(가장 일반적으로 사용되는 유형)의 경우 GNU find
,BDS find
확실히-L
특정 플래그를 사용하여 강제로 따르도록 하지 않는 한 기호 링크를 따릅니다 . [바라보다 man find
]
따라서 이 예는 다음과 같은 경우가 아니면 문제가 되지 않을 수 있습니다.힘 find
소프트 링크를 추적하려면 이 플래그를 사용하십시오 -L
. 아무튼 위험한 선택입니다.
하드 링크의 경우 find
클릭을 링크하세요.다른 파일그러나 하드 링크는 다음과 같습니다.다른 디렉토리man ln
GNU에서 와 같이 "실패할 수 있습니다" 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