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


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.