빈 디렉토리 찾기 UNIX


91

주어진 디렉토리 목록에 대해 빈 디렉토리를 찾아야합니다. 일부 디렉토리에는 내부에 디렉토리가 있습니다.

내부 디렉토리도 비어 있으면 기본 디렉토리가 비어 있다고 말할 수 있습니다. 그렇지 않으면 비어 있지 않습니다.

어떻게 테스트 할 수 있습니까?

예를 들면 :

A>A1(file1),A2 this is not empty beacuse of file1
B>B1(no file) this is empty
C>C1,C2 this is empty

2
마틴의 대답이 여기에서 가장 적절하다고 생각합니다. 현재 허용되는 답변은 불완전한 의사 코드입니다.
Léo Léopold Hertz 준영

답변:


34

find <dir> -type f출력 여부를 확인하십시오 . 예를 들면 다음과 같습니다.

for dir in A B C; do
    [ -z "`find $dir -type f`" ] && echo "$dir is empty"
done

2
아니요, 하위 디렉터리를 출력하지 않습니다. 그게 -type f목적입니다.
Marcelo Cantos

그러나 빈 파일있으면 솔루션이 메시지를 생성하지 않습니다.
Yasir Arsanukaev

3
Yasir : 빈 파일 상처를 포함하는 디렉토리 자체가 비어 있지 않다고 생각합니다. 올바른 결과가 아닐까요?
Ukko

2
@akostadinov : OP에 표시된대로 디렉토리와 파일을 만들고 mkdir A B C A/A1 A/A2 B/B1 C/C1 C/C2; touch A/A1/file1내 대답에서 코드를 실행하면 OP에서 요구하는대로 B와 C가 비어 있다고보고합니다. 따라서 "작동하지 않을 것"보다 좀 더 구체적이어야합니다.
Marcelo Cantos 2013 년

1
나 같은 Bash 멍청이라면 -z가 무엇을 의미하는지 여기 에서 확인 하십시오 .
OmarOthman

257

빈 디렉토리로 무엇을 하려는지에 따라 조금 다릅니다. 트리 내의 모든 빈 디렉토리, 즉 디렉토리 를 삭제하려면 아래 명령을 사용합니다 test.

find test -depth -empty -delete

위의 명령에 대해주의해야 할 점은 빈 파일도 제거 한다는 것이므로 -type d 옵션을 사용하여 이를 방지하십시오.

find test -depth -type d -empty -delete

-delete일치하는 파일과 디렉토리를 보려면 드롭 하십시오.

빈 디렉토리 트리의 정의에 파일이 포함되어 있지 않다면 find test -type f반환 여부에 따라 무언가를 함께 붙일 수 있습니다 .

find 훌륭한 유틸리티이며 RTFM은 초기에 그리고 종종 얼마나 많은 일을 할 수 있는지 실제로 이해합니다. :-)


8
-delete는 의미 (GNU에 대한 최소한이 4.4.2 findutils의) -depth
박사 사람 한 사람 II

4
에 대해 몰랐기 -empty때문에 편리합니다!
Raffi 2011

2
그러나 최신 및 최고의 Linux가 아닌 시스템에서. (예 : Solaris), -empty 또는 -delete와 같은 멋진 찾기 기능이 없습니다.
anthony

3
MacOS-X에서 거의 빈 디렉토리에 대해 find test -name ".DS_Store" -delete먼저 실행 한 다음 -empty delete명령을 실행합니다. 또한 pushd상위 디렉토리에 대해 좋아요를 누르면 find testfind .되지만 나머지 명령은 동일합니다.
Olie

1
@Martin -depth여기에 정의를 추가해 주시겠습니까? 즉, find가 depth-first traversal을 수행하도록합니다. 즉, 디렉토리가 사후 순서로 방문되고 디렉토리의 모든 항목이 디렉토리 자체보다 먼저 작동합니다. 여기에 관련이 있다고 생각합니다.
Léo Léopold Hertz 준영 2011-04-23

49

다음 명령을 사용할 수 있습니다.

find . -type d -empty

1
-empty는 현재 디렉토리가 완전히 비어있는 경우에만 작동하고 하위 트리에 파일이없는 경우에는 작동하지 않습니다.
Marcelo Cantos

@soField 테스트를 거쳤습니다 . -Type d -FreeBSD 및 CentOS에서 비어 있습니다. 잘 작동합니다. 당신의 OS는 무엇입니까?
mosg

1
hp-ux이므로 빈 매개 변수가 없습니다
soField

@soField 그래서, (우리 모두에게)이 데이터를 질문의 맨 위에 게시하는 것이 더 낫다는 것을 알 수 있습니다 ...
mosg

2
find는 solaris에서도 -empty를 가지고 있지 않지만, 부모 디렉토리가 비어 있는지 확인하기 전에 빈 하위 디렉토리를 삭제할 수 있도록 depth-first traversal을 시행하는 -depth가 있습니다.
eirikma 2011 년

26
find directory -mindepth 1 -type d -empty -delete

이것이 제가 가장 흥미롭게 찾은 버전입니다. 내부 directory 에서 실행하면 아래의 모든 빈 디렉터리가 삭제됩니다 (빈 디렉터리 만 포함 된 디렉터리는 빈 디렉터리로 간주 됨).

mindepth 옵션은 비어있는 경우 디렉토리 자체가 삭제되는 것을 방지합니다.


2
당신은 rmdir --ignore-fail-on-non-empty -p directory부모를 제거하기 위해 이것을 따라갈 수 있습니다 .
Pete Peterson

@Pete Peterson 내 명령은 다른 빈 디렉토리 만 포함하는 디렉토리를 제거하는 것 같습니다 (OP도 원하는 것입니다). 나는 당신의 명령이 그들이 원하는 것을 달성하더라도 누락 된 i 노드가있는 디렉토리에 사용자를 남겨 두어 혼란 스러울 수 있습니다. 요점을 놓치고있는 것 같습니다.
Dr. Person Person II

23

find . -type d -empty

현재 트리에서 빈 디렉토리와 하위 디렉토리를 찾아 나열합니다. 예 : 빈 디렉토리 및 하위 디렉토리의 결과 목록 :

./2047
./2032
./2049
./2063
./NRCP26LUCcct1/2039
./NRCP26LUCcct1/2054
./NRCP26LUCcct1/2075
./NRCP26LUCcct1/2070

디렉토리에서 작업이 수행되지 않습니다. 그들은 단순히 나열됩니다. 이것은 나를 위해 작동합니다.


16

빈 dirs를 찾으십시오.

빈 디렉토리 (질문 제목에 지정된대로)를 찾으려면 mosg의 대답 이 맞습니다.

find -type d -empty

그러나 -empty아주 오래된 find버전에서는 사용할 수 없습니다 ( 예 : HP-UX 의 경우 ). 이 경우 아래 섹션에 설명 된 기술을 참조하십시오 . 디렉토리가 비어 있습니까? .

빈 디렉토리 삭제

이것은 약간 까다 롭습니다. 디렉토리 MyDir에 빈 디렉토리가 포함되어 있다고 가정합니다 . 이러한 빈 디렉토리를 제거하면 MyDir은 빈 디렉토리가되며 제거해야합니다. 따라서 가능한 경우 부모 디렉터리도 제거 rmdir하는 옵션 --parents(또는 -p) 과 함께 명령 을 사용 합니다.

find -type d -empty -exec rmdir -vp --ignore-fail-on-non-empty {} +

이전 find버전에서는이 명령문 +이 아직 지원되지 않으므로 ;대신 사용할 수 있습니다 .

find -type d -empty -exec rmdir -vp --ignore-fail-on-non-empty {} `;`

디렉토리가 비어 있습니까?

이 답변의 대부분은 디렉토리가 비어 있는지 확인하는 방법을 설명합니다. 따라서 여기에 내가 아는 세 가지 기술을 제공합니다.

  1. [ $(find your/dir -prune -empty) = your/dir ]

    d=your/dir
    if [ x$(find "$d" -prune -empty) = x"$d" ]
    then
      echo "empty (directory or file)"
    else
      echo "contains files (or does not exist)"
    fi

    변형 :

    d=your/dir
    if [ x$(find "$d" -prune -empty -type d) = x"$d" ]
    then
      echo "empty directory"
    else
      echo "contains files (or does not exist or is not a directory)"
    fi

    설명:

    • find -prunefind -maxdepth 0적은 문자를 사용하는 것과 유사 합니다.
    • find -type d 디렉토리 만 인쇄
    • find -empty 빈 디렉토리와 파일을 인쇄합니다.

      > mkdir -v empty1 empty2 not_empty
      mkdir: created directory 'empty1'
      mkdir: created directory 'empty2'
      mkdir: created directory 'not_empty'
      > touch not_empty/file
      > find empty1 empty2 not_empty -prune -empty
      empty1
      empty2
  2. (( ${#files} ))

    이 트릭은 100 % bash이지만 하위 쉘을 호출 (스폰)합니다. 아이디어는 Bruno De Fraine에서왔으며 teambob 의 의견으로 개선되었습니다 . 나는 당신이 사용한다면 이것을 조언합니다 스크립트를 이식 할 필요가없는 경우.

    files=$(shopt -s nullglob dotglob; echo your/dir/*)
    if (( ${#files} ))
    then 
      echo "contains files"
    else 
      echo "empty (or does not exist or is a file)"
    fi

    참고 : 빈 디렉토리와 존재하지 않는 디렉토리 사이에는 차이가 없습니다 (제공된 경로가 파일 인 경우에도).

  3. [ $(ls -A your/dir) ]

    이 트릭은 2007 년에 게시 된 nixCraft의 기사 에서 영감을 얻었습니다 . Andrew Taylor 는 2008 년, gr8can8dian 은 2011 년에 답변했습니다 .

    if [ "$(ls -A your/dir)" ]
    then
      echo "contains files"
    else
      echo "empty (or does not exist or is a file)"
    fi

    또는 한 줄 bashism 버전 :

    [[ "$(ls -A your/dir)" ]] && echo "contains files" || echo "empty or ..."

    참고 : 디렉토리가 존재하지 않을 때 ls반환 $?=2됩니다. 그러나 파일과 빈 디렉토리 사이에는 차이가 없습니다.


rmdir -vp루트 아래의 모든 빈 디렉토리를 삭제하는 것이 아니라 파일을 삭제 한 후 빈 디렉토리와 부모 디렉토리를 확인해야했기 때문에 매우 도움이되었습니다. 내 상황에서는 현재 파일을 제거하고있는 트리에없는 한 빈 디렉토리는 괜찮습니다. 감사!
에단 Hohensee

2

이 재귀 함수는 트릭을 수행하는 것처럼 보입니다.

# Bash
findempty() {
    find ${1:-.} -mindepth 1 -maxdepth 1 -type d | while read -r dir
    do
        if [[ -z "$(find "$dir" -mindepth 1 -type f)" ]] >/dev/null
        then
            findempty "$dir"
            echo "$dir"
        fi
    done
}

이 예제 디렉토리 구조가 주어지면 :

    .
    |-dir1 /
    |-dir2 /
    | `-dirB /
    |-dir3 /
    | `-dirC /
    | `-file5
    |-dir4 /
    | |-dirD /
    | `-file4
    `-dir5 /
        `-디렉토리 /
            `-dir_V /

해당 함수를 실행 한 결과는 다음과 같습니다.

    ./dir1
    ./dir5/dirE/dir_V
    ./dir5/dirE
    ./dir5
    ./dir2/dirB
    ./dir2

그리워 /dir4/dirD합니다. 당신은 재귀 호출 이동하면 findempty "$dir"애프터을 fi, 함수는 그 결과에 해당 디렉토리에 포함됩니다.


2

어때요 rmdir *? 이 명령은 비어 있지 않은 디렉토리에서 실패합니다.


일반적인 청소를 위해 내가 때때로 한 일. 또한 rmdir */*/* */* * '도트 파일'을 처리하지 않지만 수동 상황 (데이터 파일 정리)에서는 일반적으로 '도트 파일'을 기대하지 않습니다. 그러나 재귀 방법은 특히 매우 큰 디렉토리 구조에서보다 자동화 된 일반 정리를위한 것입니다.
anthony

하나의 'readme'파일을 포함 할 수있는 'empty'디렉토리가 포함 된 빈 디렉토리를 제거해야했기 때문에 한 경우 더 복잡했습니다. 디렉토리의 다른 항목은 '비어 있지'않았습니다. 이 예에서 디렉터리 구조에는 수만 개의 하위 디렉터리가 포함되었습니다.
anthony

1

다음 명령은 디렉토리가 비어 있거나 존재하지 않으면 1을 반환하고 그렇지 않으면 0을 반환합니다 ( !셸 스크립트에서 반환 코드를 반전 할 수 있음 ).

find $dir -type d -prune -empty -exec false {} +

0

다음과 같이 간단한 구조를 만들었습니다.

test/
test/test2/
test/test2/test2.2/
test/test3/
test/test3/file

test/test3/file정크 텍스트가 있습니다.

실행 하면 find test -empty" test/test2/test2.2"이 (가) 유일한 빈 디렉토리로 반환 됩니다.


op는 test / test2도 반환하도록 요청합니다

과연. 그러나 나는 그가 더 나아 가기 위해 find man 페이지를 읽을 수 있다고 생각했습니다. 결과에 따라 깊이를 조정하는 스크립트는 잘 작동합니다.
James Sumners

이 덕분에 MYE 사용을위한 가장 유용한 버전이었다
안드레아스

0

간단한 접근 방식은

$ [ "$(ls -A /path/to/direcory)" ] && echo "not empty" || echo "its empty"

또한,

if [ "$(ls -A /path/to/direcory)" ]; then
   echo "its not empty"
else 
   echo "empty directory"

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