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


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 fortest더 좋은 친구입니다 ...>
바이트 사령관

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.