`find` 출력을 기반으로 디렉토리를 삭제하는 방법은 무엇입니까?


148

.svn 디렉토리를 찾으려면 다음 명령을 실행하십시오.

find . -name ".svn"

결과는 다음과 같습니다.

./toto/.svn
./toto/titi/.svn
./toto/tata/.svn

rm -fr디렉토리와 그 내용을 삭제하기 위해이 모든 줄을 어떻게 처리 할 수 있습니까?


3
GNU find에는 -delete옵션이 있습니다.
Marco

5
또는 -exec rm -r "{}" \;찾기 끝에 추가 할 수 있습니다 rm -r. 사용시주의하십시오 ! :)
Drav Sloan

10
@Marco 삭제 옵션이 디렉토리에서 작동하지 않는 것 같습니다.
Arnaud

@SuperChafouin 파일과 디렉토리에서 완벽하게 작동합니다. 요점은 emtpy 디렉토리 만 삭제한다는 것입니다. 지정 -name ".svn"하면 .svn디렉토리 자체에 있고 디렉토리에있는 파일 은 일치 하지 않습니다 .svn.
Marco

1
@SuperChafouin이지만 공백이있는 경로에서는 작동하지 않습니다 (따라서 -exec인용 된 "{}").
Drav Sloan

답변:


194

찾기는 -exec찾은 각 일치에 대한 옵션으로 인수를 실행할 수 있습니다 . 공백 / 줄 바꿈 및 기타 문자가 포함 된 경로를 올바르게 처리 할 수 ​​있으므로 권장되는 메커니즘입니다. 디렉토리 자체를 제거하기 전에 디렉토리의 내용을 삭제해야하므로 이를 수행 -r하려면 rm명령 과 함께 사용 하십시오.

예를 들어 다음을 발행 할 수 있습니다.

find . -name ".svn" -exec rm -r "{}" \;

또한 확인 을 추가하여 .svn이라는 디렉토리 만 찾도록 find에 지시 할 수 있습니다 -type d.

find . -name ".svn" -type d -exec rm -r "{}" \;

경고rm -r 주의해서 사용 하면 폴더와 모든 내용이 삭제됩니다.

빈 디렉토리와 빈 디렉토리 만 포함 된 디렉토리 만 삭제하려면 find는 다음 -delete-empty같이 수행 할 수 있습니다 .

find . -name ".svn" -type d -empty -delete

21
난 항상 실행 조언을 본 -type -name 호출에 있기 때문에 찾기 명령에이 stat유형을 얻는이 비싸다. 방금 상당히 많은 파일에서 직접 시도했지만 실제로 find . -name 'foo' -type d는 실행하는 데 19 초가 걸리고 find . -type d -name 'foo'32 초가 걸렸습니다. 따라서 -type첫 실행 시간이 약 50 % 더 길었습니다 .
spinup

6
나는 수년 동안이 명령을 사용해 왔지만 Mac에서는 이제 해당 디렉토리가 존재하지 않는다는 오류가 발생합니다. 비록 그것을 삭제하더라도. 나는 전에 메시지를 본 적이 없다.
chovy

1
@chovy와 동일합니다. 이러한 메시지를 제거 할 수있는 방법이 있습니까?
Clément

2
@chovy @ clément find폴더를 동시에 제거하는 동안 해당 폴더에서 다른 일치 항목을 보려고 하기 때문 입니다. ~ 아직이 문제를 해결하는 방법을 모르겠습니다. ~ 더티 픽스 :find . -name "folder-to-delete" -print0 | xargs -r0 -- rm -r
Charlie

5
@chovy @ Clément 나는 -depth논쟁이 이것을 해결 한다고 생각한다 :find . -depth -name ".svn" -type d -exec rm -r "{}" \;
gimboland

67

여기에 여전히 휴대용 답변이 허용되는 답변 방법보다 빠릅니다.

사용 +하는 대신 같은 세미콜론의 find명령 종료가 CPU의 사용을 최적화한다. 많은 .svn하위 디렉토리 가있는 경우 이는 중요 할 수 있습니다 .

find . -name .svn -type d -exec rm -rf {} +

당신은 결코 것 또한주의 일 개 필요가 여기에 중괄호를 인용.

1fish 쉘 을 사용하지 않는 한 .


5
+와 세미콜론의 차이점은 무엇입니까? 왜 중괄호를 사용하지 않습니까?
Shicheng Guo

1
@ShichengGuo 세미콜론을 사용하면 디렉토리마다 하나의 rm 명령이 있으며 + 하나의 rm 명령은 발견 된 모든 디렉토리를 처리합니다 (또는 적어도 매우 많은 수). 두 번째 질문은 곱슬하지 않습니다. 여기서는 중괄호가 사용됩니다.
jlliagre

@ShichengGuo는 왜 중괄호를 인용 할 필요가 없다는 것을 의미한다고 생각 합니다 (@jlliagre는 인용 할 필요가 없다고 썼습니다). 현재 참조를 찾을 수 없지만 find는 {}로 대체 된 경로를 자동으로 이스케이프하기 때문에 이해합니다.
Quinn Comendant

대답과 질문은 + 가하는 일에 옳지 않습니다. 많은 파일이 발견되면 ';' '명령 줄이 너무 깁니다'오류가 발생합니다. + 최대 허용 명령 줄 길이보다 작은 배치에서 찾은 파일을 분할하고 각 배치에 대해 명령을 실행합니다.
gaoithe

1
@gaoithe 올바른 문장을 잘못된 문장으로 대체 한 편집을 롤백했습니다. 를 사용 하면 CPU 사용량 + 줄어들고, 너무 오래 사용 하면 명령이 너무 길지 ; 않습니다 .
jlliagre

27

gnu find를 사용한다고 가정하면 다음 -delete옵션을 사용할 수 있습니다 .

find . -name test -delete

기억하기가 더 쉽습니다.


명령에 대한 설명 (또는 솔루션을 백업하기위한 문서)으로 게시물을 확장하십시오. 종종 하나 또는 두 개의 줄 답변이 가장 밝지 않습니다.
HalosGhost

94
비어 있지 않은 디렉토리에서는 작동하지 않습니다.
belacqua

2
또한 맥 OS X에서 작동
무승부

비어 있지 않은 폴더에서는 작동하지 않지만 더 쉽고 안전한 솔루션입니다
RousseauAlexandre

옵션의 순서는 매우 중요하므로, -delete 마지막 하나가 될 필요가 순서대로 실행됩니다 찾을
호세 이그나시오 센테노

13

사용할 때 내 컴퓨터에서 :

find . \( -name dirname -type d \) -exec rm -r '{}' ';'

디렉토리가 삭제되었지만 오류가 발생합니다.

find: ‘./dirname’: No such file or directory

각 디렉토리마다.

내 디렉토리가 비어 있지 않으므로 -delete 옵션이 작동하지 않습니다. 나는이 행동의 이유를 여기서 발견했다 .

  1. find는 반드시 ./ 디렉토리의 첫 번째 항목을 가져옵니다. 예를 들어 dir.1 /
  2. 패턴 'dir.?'과 비교합니다. 일치합니까? 예.
  3. find는 "rm -r dir.1"을 실행합니다.
  4. find는 디렉토리 내에서 패턴을 찾기 위해 dir.1 /을 입력하려고 시도합니다. exec 명령에 대해서는 아무것도 모릅니다.
  5. 더 이상 dir.1 /을 찾지 못합니다. ENOENT를 리턴합니다 (strace 출력을보십시오).

대신 이것을 사용하여 해결했습니다.

rm -r `find . -name dirname -type d`

find는 여전히 dirname이라는 디렉토리로 재귀를 시도하지만 실제로는 필요하지 않으며 추가 시간이 걸립니다. 디렉토리 구조에 따라 --depth찾기 옵션 으로이 문제를 해결할 수 있습니다. 또한 dirname / foo / dirname과 같은 디렉토리 구조가 있으면 rm에서 "그러한 파일이나 디렉토리가 없습니다"오류가 발생합니다. 오류를 억제하기 위해 stderr을 / dev / null로 경로 재 지정하거나 -frm과 함께 (force) 플래그를 사용할 수 있습니다 .


2
나쁜 생각 : 공백이있는 파일 이름은 모든 종류의 끔찍한 문제를 일으킬 것입니다
Clément

2
미래 독자들을 위해 : find . -name "to-delete" -print0 | xargs -r0 -- rm -r우주에서 충돌하지 않는 고장 방지 버전입니다
Charlie

3
추가해야하는 unix.stackexchange.com/a/115869/8257 을 참조하십시오 -prune.
Mapio

1
-prune"No such file or directory"오류가 발생하지 않도록 추가하십시오 .
Julien Carsique

12

가장 빠른 방법은 다음과 같습니다.

find . -name ".svn" -type d -prune -exec rm -rf '{}' '+'

다른 ".svn"안에 ".svn"이있는 경우


하위 디렉토리로 삭제할 디렉토리를 찾으려면별로 유용하지 않습니다.
Alexis Wilke

5

배쉬 전용 솔루션 :

shopt -s globstar
rm -r **/.svn
shopt -u globstar #optional. this will disable globstar expansion

3
많은 파일과 일치하는 glob의 명령 줄 확장을 위해이 메커니즘과 일치시킬 수있는 파일 수에는 제한이 있습니다. 이 한도를 초과가는 것은에서 발생합니다bash: /bin/rm: Argument list too long
Drav 슬로안

1
@DravSloan은 정확하지만 그 한계는 수십만 개의 파일에 있습니다. 명심해야 할 것이지만 대부분의 사람들에게는 문제가되지 않을 것입니다.
evilsoup

4

나는 그 -delete행동이 -path테스트에서 잘 작동 한다는 것을 알았습니다 . 예를 들어, 다음은 원래 포스터 문제에서 작동해야합니다.

find . -path '*/.svn*' -delete

확실합니까? -delete의미 -depth하고 내 시스템에서 비어 있지 않은 디렉토리를 삭제합니다.
Magnus

다시 테스트하고 작동합니다. 어쩌면 내가 교정 한 오타 일 수도 있습니다.
kenorb

나는 또한이 접근법을 시도하고 효과가있었습니다-디렉토리가 삭제되었습니다.
Allan
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.