빈 디렉토리 트리를 제거하십시오 (가능한 한 많은 디렉토리를 제거하지만 파일은 제거하지 마십시오)


13

다음과 같은 디렉토리가 있다고 가정하십시오.

ROOTDIR
    └--SUBDIR1
        └----SUBDIR2
            └----SUBDIR3

입력 할 때 다음과 같은 명령을 찾고 있습니다.

$ [unknown command] ROOTDIR

파일이없고 전체 트리 안에 디렉토리 만 있으면 전체 디렉토리 트리를 삭제할 수 있습니다 . 그러나 SUBDIR1 아래에 hello.pdf라는 파일이 있다고 가정하십시오.

ROOTDIR
    └--SUBDIR1
        └--hello.pdf
        └----SUBDIR2
            └----SUBDIR3

그런 다음 명령은 SUBDIR2 이하 만 삭제해야합니다.


답변:


11

알렉시스가 가까워 당신이해야 할 일은 이것입니다 :

find . -type d -depth -empty -exec rmdir "{}" \;

먼저 첫 번째 빈 디렉토리를 찾을 때까지 디렉토리 트리를 드릴 다운 한 다음 삭제합니다. 따라서 부모 디렉토리를 비우면 삭제 될 것입니다. 이것은 원하는 효과를 낼 것입니다 (일주일에 10 번 정도 할 것이므로 옳습니다). :-)


-depth옵션이 필요한가요? find . -type d -empty -exec rmdir "{}" \;작동해야합니다 .... 맞습니까?
Abhishek A

4
나무가 있다면 (디렉토리 만) 고려하십시오 foo/bar/baz. 을 사용하지 않으면 먼저 -depth삭제하려고 시도하고 foo실패하며 foo/bar실행 후에 끝납니다 .
l0b0

1
디렉토리 +대신 ;배치를 제거 하는 대신에 다른 방법을 사용 하는 것이 가능 합니다. 깊이 우선 순위를 수행하기 때문에 자식은 부모보다 먼저 제거됩니다 (rmdir / bash 버전에 따라 다르며 비어 있지 않은 디렉토리를 삭제하지 않는 rmdir에 의존 할 수 있음). 이것은 cygwin의 bash에서 나를 위해 작동합니다 :mkdir -p a/b/c/d ; find a -depth -type d -exec rmdir {} +
idbrii

4
사람들, 아래 go2null의 더 간결한 답변을 찾으십시오! 질문 아래에 답변을 표시 할 때 대부분의 공감대가있는 답변보다는 SE가 수락 된 답변에 우선 순위를 부여하는 이유를 이해할 수 없습니다. OP는 자신이 선택했을 때 사용 가능한 최상의 답변을 받아들이지 만 나중에 커뮤니티가지지하는 훨씬 더 나은 답변을 얻을 수 있습니다. (물론,이 메타 뭔가 ...입니다)
jamadagni

이것은 나를 위해 작동하지 않습니다. 그것은 단지 (이 경우 SUBDIR3)에 최심 잎을 삭제합니다
조이 바룩에게

24
find ROOTDIR -type d -empty -delete

와 동일

find ROOTDIR -type d -depth -empty -exec rmdir "{}" \;

내장 된 "-delete"조치를 사용합니다.

"-delete"는 "-depth"를 의미합니다.


find 자체 내장 삭제를 사용하여 가장 간결한 답변을 얻으십시오! 이것을 로컬 유틸리티에 추가하고 있습니다!
jamadagni

3

나는 이것을 시도 할 것이다 :

find ROOTDIR -type d -depth -exec rmdir {} \;

1

안전하게 수행하기 전에 몇 가지 요구 사항이 있습니다.

  1. 하위 디렉토리를 먼저 제거한 다음 상위 디렉토리를 제거하십시오. 즉, 디렉토리 목록을 정렬하거나 rmdir --parents 플래그를 사용해야합니다.
  2. -로 시작하는 파일로 인한 놀라움을 피하려면 항상 / 또는 ./로 ROOTDIR을 시작하십시오.
  3. 공백이있는 디렉토리 이름으로 작업하려면 NUL 종료 디렉토리 목록을 사용하십시오.

다음은 셸에서 수행하는 방법입니다.

find ./ROOTDIR -type d | sort -r | tr '\n' '\000' | xargs -0 rmdir --ignore-fail-on-non-empty

중복 오류가 마음에 들지 않으면 부모와 함께 모든 디렉토리를 강제로 제거하고 정렬 할 필요가 없습니다 (tr에 추가 해야하는 NUL 종료 문자열을 정렬 할 수 없음)

find ./ROOTDIR -type d -print0 | xargs -0 rmdir --ignore-fail-on-non-empty --parents

답변에 대한 자세한 설명을 알려주세요. @ go2null의 답변에 대한 -empty -delete옵션에 대해 배울 때까지 아마도 같은 접근법을 사용했을 것입니다 find.
Davor Cubranic

0
rmdir $(find ROOTDIR -type d | sort -r)

5
디렉토리 이름에 공백이나 globbing 문자가 포함되어 있으면 작동하지 않습니다. 일반적으로 파일 이름 목록에서 명령 대체를 사용하는 것은 좋지 않습니다. 처리를 깨끗하게 수행 할 수있는 방법 이 find있기 때문에 특히 나쁜 생각입니다 . findfind … -exec
Gilles 'SO- 악마 그만

지적 해 주신 Gilles에게 감사합니다. @lanzz, 일반적으로 명령을 게시하지 않고 명령을 게시하는 것만으로는 충분하지 않습니다. 답변에 추가하십시오.
n0pe

0

나는 이것을 할 것이다 :

find ROOTDIR -type d | xargs -0 -I {} rmdir {}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.