하나와 그 하위 항목을 제외한 상위 디렉토리에서 모든 디렉토리를 제거하십시오.


8

디렉토리 구조

디렉토리 B와 D를 제거하고 싶지만 C와 모든 하위 파일과 디렉토리를 유지하고 싶습니다. 하나의 디렉토리와 그 하위를 제외한 상위 디렉토리의 모든 하위 디렉토리를 제거하는 명령은 무엇입니까?

감사합니다.


제거하려는 디렉토리가 비어 있습니까?
— Geek


부모 디렉토리에 직접있는 파일은 A어떻습니까? 그것들을 삭제하거나 보관 하시겠습니까?
— 바이트 사령관

Byte Commander가 묻는 것은 A에 파일이 있습니까? 아니면 디렉토리 만? A의 일반 파일을 제거 하시겠습니까, 아니면 디렉토리 만 원하십니까?
— Sergiy Kolodyazhnyy

답변:


6

원하는 것은이 명령입니다.

find ~/TESTDIR -mindepth 1 -maxdepth 1 -type d -not \( -name "keepMe" \) -exec rm -rf {} \;

데모:

# List what's inside directory we want to remove
$ ls
file1  file2  keepMe/  removeA/  removeB/
# Testing what find gives without removing
$ find ~/TESTDIR -mindepth 1 -type d -not \( -name "keepMe" \)               
/home/xieerqi/TESTDIR/removeA
/home/xieerqi/TESTDIR/removeB
# Actual removal and testls
$ find ~/TESTDIR -mindepth 1 -maxdepth 1 -type d -not \( -name "keepMe" \) -exec rm -rf {} \;
$ ls
file1  file2  keepMe/

설명:

  • find DIRECTORY DIRECTORY에서 작동하는 find 명령을 호출하십시오.
  • -mindepth 1 : 디렉토리의 내용으로 만 작업하고 레벨 0 인 디렉토리 자체는 피하십시오.
  • -maxdepth 1: 하위 디렉토리로 내려가는 것을 방지합니다 ( rm -rf어쨌든 재귀 적이므로 하위 디렉토리로 내려갈 필요가 없습니다)
  • -type d : 디렉토리 만 검색
  • -not \( -name "keepMe" \) 유지하려는 이름의 항목을 무시하십시오.
  • -exec rm -rf {} \; 발견 된 각 항목에서 제거를 수행

좋은 설명입니다. 나를 위해 너무 많은 키 입력 ...
— 장로 eek

1
find여기 좋은 친구이지만 Bash for와 test더 좋은 친구입니다 ...>
— 바이트 사령관

8

bash 쉘의 확장 글롭 기능 사용 (현재 우분투 설치에서 기본적으로 활성화 됨)

$ tree A
A
├── B
├── C
│   ├── ac1
│   └── ac2
└── D

5 directories, 0 files

당신은을 제외한 모든 것을 해결할 수 C와 그 내용물 글로브 표현의 사용 A/!(C)예를

$ echo A/!(C)
A/B A/D

따라서 디렉토리 와 그 내용을 제외한 모든 것을 제거C 하려면 간단히 사용할 수 있습니다

rm -rf A/!(C)

퇴거

$ tree A
A
└── C
    ├── ac1
    └── ac2

3 directories, 0 files

이 기능에 대해 아는 것이 놀랍습니다. 그것은 ssh와 수동으로 실행 한 후에 훌륭하게 작동하지만` "-bash : line 1 : ('"원격으로 실행할 때 예기치 않은 토큰 근처에 구문 오류가 발생합니다 ssh $VM_ADDRESS "rm -rf $APP_FOLDER/!(node_modules)". 어떤 아이디어라도 감사합니다.
— Renato Gama

@renatoargh extglob쉘 옵션은 대화식 쉘에서만 사용할 수 있습니다. 강제 ssh로 할 수 있는지 확실하지 않습니다
— steeldriver

5

하나의 쉬운 방법은 휴지통을 사용하는 것입니다

당신은 그것을 설치할 수 있습니다 sudo apt-get install trash-cli

일단 설치되면 부모 디렉토리 A로 이동 cd /A한 다음 trash B DB와 D가 제거하려는 디렉토리 인 명령을 발행 할 수 있습니다 (실제로 드라이브에 대한 휴지통에서 결국 실수를 할 수 있습니다) 파일을 복구)

우분투 16.04 및 14.04에서 테스트


이것은 다음과 같이 단순화 될 수 trash ! C있습니까?
— Sergiy Kolodyazhnyy

@Serg Nope trash: cannot trash non existent ! '`
— Geek

@Serg와 C는 휴지통에 빠진다 ...
— Geek

그것을 찾았습니다 : stackoverflow.com/q/216995/3701431extglob 그래도 활성화해야합니다 .
— Sergiy Kolodyazhnyy

@Serg 현재 작업에 따라 매우 유용 할 수 있습니다! ;-)
— Geek

4

Bash의 for루프를 사용 test하고 원하는 디렉토리를 필터링하고 다음과 rm -rf같이 디렉토리를 재귀 적으로 삭제 하는 명령을 필터링하십시오 .

for x in /path/to/parent/*; do test "$x" != "dir_survive" && rm -rf "$x"; done

내부의 모든 요소 (파일 및 디렉토리)를 /path/to/parent/반복하고 이름이 같지 않으면 요소를 재귀 적으로 삭제합니다 dir_survive. 상위 디렉토리가 현재 디렉토리 인 경우 *경로 로만 쓸 수 있습니다 .

확실하지 않고 어떤 조치를 취하지 않고 먼저 삭제 될 요소를 테스트하려는 경우 rm -rf위의 명령 echo에서를 바꾸면 삭제 후보 만 출력됩니다.

다음은 예제 실행입니다.

$ tree
.
├── dir1
│   ├── subdir1
│   │   ├── file1
│   │   └── file2
│   └── subdir2
│       ├── file1
│       └── file2
├── dir2
│   ├── subdir1
│   │   ├── file1
│   │   └── file2
│   └── subdir2
│       ├── file1
│       └── file2
└── dir_survive
    ├── subdir1
    │   ├── file1
    │   └── file2
    └── subdir2
        ├── file1
        └── file2

9 directories, 12 files

$ for x in *; do test "$x" != "dir_survive" && rm -rf "$x"; done

$ tree
.
└── dir_survive
    ├── subdir1
    │   ├── file1
    │   └── file2
    └── subdir2
        ├── file1
        └── file2

3 directories, 4 files
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.