空のディレクトリを見つける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
ここではマーティンの答えが最も適切だと思います。現在受け入れられている答えは、不完全な疑似コードのみです。
レオ・レオポルド・ヘルツ준 영

回答:


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:空のファイルを含むディレクトリ自体は空ではないと思います。それは正しい結果ではないでしょうか?
ウッコ

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 noobの場合は、ここで -zの意味を確認してください
OmarOthman 2017

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は-depthを意味します(少なくともGNU findutils 4.4.2の場合)
Dr Person Person II

4
について知らなかった-emptyので、とても便利です!
ラフィ2015年

2
ただし、最新かつ最高のLinuxではないマシンでは。(例えば、Solaris)、-emptyや-deleteなどの特別な検索機能はありません。
anthony 2016

3
MacOS-Xでは、ほとんど空のディレクトリに対して、find test -name ".DS_Store" -delete最初に実行し、次に-empty deleteコマンドを実行します。またpushd、親ディレクトリに似ているので、にfind testなりfind .ますが、残りのコマンドは同じです。
Olie

1
@Martin -depthここに定義を追加してください。つまり、 findが深さ優先のトラバーサルを実行するようにします。つまり、ディレクトリはポストオーダーでアクセスされ、ディレクトリ内のすべてのエントリはディレクトリ自体の前に作用します。ここでも関係があると思います。
レオ・レオポルド・ヘルツ준 영

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があります。
eirikma 2011年

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

これは私が最も興味深いと思ったバージョンです。directoryの内部から実行すると、以下の空のディレクトリがすべて削除されます(空のディレクトリのみが含まれている場合、そのディレクトリは空と見なされます)。

mindepthオプションは、ディレクトリが空の場合でも削除されないようにします。


2
これをフォローアップしrmdir --ignore-fail-on-non-empty -p directoryて、親を取り除くこともできます。
ピートピーターソン

@Pete Peterson私のコマンドは、他の空のディレクトリのみを含むディレクトリを削除するようです(これもOPが望んでいるようです)。私はあなたのコマンドは通常彼らが望んでいることを成し遂げても紛失したiノードのあるディレクトリにユーザーを残すことに注意してください、それは彼らを混乱させるかもしれません。多分私はポイントを逃しています。
パーソンパーソンII

23

find . -type d -empty

現在のツリーで空のディレクトリとサブディレクトリを見つけてリストします。たとえば、空のディレクトリとサブディレクトリの結果のリスト:

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

ディレクトリに対する操作は行われません。それらは単にリストされています。これでうまくいきます。


16

空のディレクトリを見つけるだけです

空のディレクトリ(質問のタイトルで指定)を見つけるだけの場合、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 {} `;`

ディレクトリは空ですか?

これらの回答のほとんどは、ディレクトリが空かどうかを確認する方法を説明しています。したがって、私はここで私が知っている3つの異なるテクニックを提供します。

  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 -pruneよりfind -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) ]

    インスピレーションを得ているこのトリックnixCraftの記事は、 2007年に投稿されたアンドリュー・テイラー 2008年に答えてgr8can8dian 2011インチ

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

    または1行のバシズムバージョン:

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

    注: ディレクトリが存在しない場合にls戻ります$?=2。しかし、ファイルと空のディレクトリの間に違いはありません。


rmdir -vpルートの下にあるすべての空のディレクトリを削除するだけでなく、ファイルを削除した後に空のディレクトリと親ディレクトリを確認する必要があったので、非常に役に立ちました。私の状況では、現在ファイルを削除しているツリーにない限り、空のディレクトリは問題ありません。ありがとう!
Ethan 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 /
        `-dirE /
            `-dir_V /

その関数を実行した結果は次のようになります。

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

ミスし/dir4/dirDます。のfindempty "$dir"後に再帰呼び出しを移動するfiと、関数はそのディレクトリを結果に含めます。


2

いかがrmdir *ですか?このコマンドは、空でないディレクトリでは失敗します。


一般的な片付けのために、時々行ったこと。また、 rmdir */*/* */* * 「ドットファイル」は処理しませんが、手動の状況(データファイルのクリーニング)では、通常「ドットファイル」は期待していません。ただし、再帰的な方法は、特に非常に大きなディレクトリ構造で、より自動化された一般的なクリーンアップ用です。
anthony 2016

空のディレクトリを1つ削除する必要があったため、1つのケースではさらに複雑でした。ディレクトリ内のその他のもので、「空」ではなかった。その例では、ディレクトリ構造には数万のサブディレクトリが含まれていました。
anthony 2016

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で使用するのに最も便利なバージョンでした。ありがとう
Andreas 14

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.