특정 이름을 가진 폴더를 제외한 폴더 내의 모든 폴더 삭제


18

매일 스크립트를 사용하여 폴더 내의 모든 폴더를 삭제해야합니다. 그 날의 폴더는 남겨 두어야합니다.

'myfolder'폴더에는 'test1', 'test2'및 'test3'이라는 3 개의 하위 폴더가 있습니다. 'test2'를 제외한 모든 폴더를 삭제해야합니다.

여기서 정확한 이름을 찾으려고합니다.

find /home/myfolder -type d ! -name 'test2' | xargs rm -rf

또는

find /home/myfolder -type d ! -name 'test2' -delete

이 명령은 항상 기본 폴더 'myfolder'도 삭제하려고합니다! 이것을 피할 수있는 방법이 있습니까?


6
유닉스와 리눅스에서는 이것을 "폴더"가 아니라 "디렉토리"라고 부릅니다.
tchrist

1
쉘에 따라 해당 !연산자 를 인용해야 할 수도 있습니다 : \!또는 '!'.
Toby Speight

답변:


32

그러면 폴더를 ./myfolder제외한 모든 폴더가 삭제 ./myfolder/test2되고 모든 내용이 유지됩니다.

find ./myfolder -mindepth 1 ! -regex '^./myfolder/test2\(/.*\)?' -delete

작동 원리

  • find 찾기 명령을 시작합니다.
  • ./myfolderfind가 디렉토리 ./myfolder와 그 내용 으로 시작하도록 지시 합니다.

  • -mindepth 1 일치하지 않고 ./myfolder그 아래의 파일과 디렉토리 만 일치 시킵니다.

  • ! -regex '^./myfolder/test2\(/.*\)?' find가 !정규 표현식과 일치하는 모든 파일 또는 디렉토리 를 제외하도록 지시 합니다 ^./myfolder/test2\(/.*\)?. ^경로 이름의 시작과 일치합니다. 이 표현 (/.*\)?은 (a) 슬래시 뒤에 무엇이든 또는 (b) 전혀 일치하지 않습니다.

  • -delete 일치하는 (즉, 제외되지 않은) 파일을 삭제하도록 find에 지시합니다.

다음과 같은 디렉토리 구조를 고려하십시오.

$ find ./myfolder
./myfolder
./myfolder/test1
./myfolder/test1/dir1
./myfolder/test1/dir1/test2
./myfolder/test1/dir1/test2/file4
./myfolder/test1/file1
./myfolder/test3
./myfolder/test3/file3
./myfolder/test2
./myfolder/test2/file2
./myfolder/test2/dir2

find 명령을 (없이 -delete) 실행하여 일치하는 것을 볼 수 있습니다.

$ find ./myfolder -mindepth 1 ! -regex '^./myfolder/test2\(/.*\)?'
./myfolder/test1
./myfolder/test1/dir1
./myfolder/test1/dir1/test2
./myfolder/test1/dir1/test2/file4
./myfolder/test1/file1
./myfolder/test3
./myfolder/test3/file3

남은 파일을 살펴보면 이것이 작동하는지 확인할 수 있습니다.

$ find ./myfolder
./myfolder
./myfolder/test2
./myfolder/test2/file2
./myfolder/test2/dir2

1
하위 디렉토리 -prune를 그대로 두는 대안 test2/*/:로 돌아가서 rm -r추가하십시오 -maxdepth 1.
Toby Speight

@Isaac OK. 끝난. (또한 탁월한 답변을
얻으

훌륭합니다!하지만 죄송합니다 : 안의 모든 파일 을 제거합니다 ./myfolder. 당신은 실종 (IMVHO)가 필요 -type d에 대한 유일한 디렉토리 .
Isaac

좋아, 이것은 당신이 원하는대로 작동합니다 :find ./myfolder -depth -mindepth 1 -maxdepth 1 -type d ! -regex '^./myfolder/test2\(/.*\)?'
아이작

10

bash 사용 :

shopt -s extglob
rm -r myfolder/!(test2)/

예:

$ tree myfolder/
myfolder/
├── test1
│   └── file1
├── test2
│   └── file2
└── test3
    └── file3

$ echo rm -r myfolder/!(test2)
rm -r myfolder/test1 myfolder/test3
$ rm -r myfolder/!(test2)
$ tree myfolder/
myfolder/
└── test2
    └── file2

1 directory, 1 file

5

tl; dr

find ./myfolder -mindepth 1 -maxdepth 1 -type d -not -name test2 \
     -exec echo rm -rf '{}' \;

파일 목록에 만족하면 에코를 제거하십시오.


를 사용 -mindepth 1하면 최상위 디렉토리가 선택되지 않습니다.

$ find ./myfolder -mindepth 1 -type d
./myfolder/test2
./myfolder/test2/one
./myfolder/test2/two
./myfolder/test
./myfolder/test/a1
./myfolder/test/a1/a2
./myfolder/test/a1/a2/a3

그러나이 -not -name test2됩니다 하지 하위 디렉토리를 내부 피하기 test2:

$ find ./myfolder -mindepth 1 -type d -not -name 'test2'
./myfolder/test2/one
./myfolder/test2/two
./myfolder/test
./myfolder/test/a1
./myfolder/test/a1/a2
./myfolder/test/a1/a2/a3

그렇게하려면 자두와 같은 것이 필요합니다.

$ find ./myfolder -mindepth 1 -name test2 -prune -o -type d -print
./myfolder/test
./myfolder/test/a1
./myfolder/test/a1/a2
./myfolder/test/a1/a2/a3

그러나 사용하지 않는 delete것이 있듯이, depth그 가장 긴 경로에서 삭제하기 시작합니다 :

$ find ./myfolder -depth -mindepth 1 -name test2 -prune -o -type d -print
./myfolder/test/a1/a2/a3
./myfolder/test/a1/a2
./myfolder/test/a1
./myfolder/test

사용하십시오 rm -rf( echo실제로 지우려면를 제거하십시오 ).

$ find ./myfolder -mindepth 1 -name test2 -prune -o -type d -exec echo rm -rf '{}' \;
rm -rf ./myfolder/test
rm -rf ./myfolder/test/a1
rm -rf ./myfolder/test/a1/a2
rm -rf ./myfolder/test/a1/a2/a3

또는, 또한 사용 maxdepth당신이 필요로하는 모든 디렉토리 (그리고 모든 것을 내)을 삭제합니다 (를 제거하는 경우 echo실제로 지우려면) :

$ find ./myfolder -mindepth 1 -maxdepth 1 -type d -not -name test2 -exec echo rm -rf '{}' \;
rm -rf ./myfolder/test

-delete디렉토리가 비어 있지 않으면 A 는 여전히 실패합니다.

$ find ./myfolder -mindepth 1 -maxdepth 1 -type d -not -name test2 -delete
find: cannot delete ‘./myfolder/test’: Directory not empty

2

zsh를 사용하는 경우 다음을 수행 할 수 있습니다.

setopt extended_glob # if you don't have it enabled

rm -rf myfolder/^test2

0

아래 명령으로 테스트했으며 정상적으로 작동했습니다.

find  /home/myfolder -maxdepth 1 -type d ! -iname test2 -exec rm -rvf {} \;

OP와 같은 문제가 발생했습니다. 명령 줄에 / home / folder를 나열하면 (임계 값없이 -mindepth 1) 최상위 디렉토리가 모든 기준 (디렉토리이고 "test2"라는 이름이 아님)과 일치하므로 삭제됩니다.
Jeff Schaller
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.