it-swarm-ko.tech

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

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

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

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

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

OR

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

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

19
Riju Mahna

./myfolder를 제외한 ./myfolder/test2 내의 모든 폴더가 삭제되고 모든 내용이 보존됩니다.

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

작동 원리

  • find는 찾기 명령을 시작합니다.
  • ./myfolder는 find에게 디렉토리 ./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
33
John1024

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
10
Jeff Schaller

tl; dr

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

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


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

$ 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 test2nottest2 내의 하위 디렉토리를 피합니다.

$ 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

이를 위해서는 Prune과 같은 것이 필요합니다.

$ 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

Butdelete을 의미하지 않으므로 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

또는 also 필요한 경우 maxdepth을 사용하면 디렉토리 (및 내부의 모든 항목)를 삭제하기 만하면됩니다 (실제로 지우려면 echo 제거).

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

디렉토리가 비어 있지 않으면 -delete가 계속 실패합니다.

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

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

setopt extended_glob # if you don't have it enabled

rm -rf myfolder/^test2
2
JoL

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

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