与えられたディレクトリのリストに対して空のディレクトリを見つける必要があります。一部のディレクトリには、その中にディレクトリがあります。
内部ディレクトリも空の場合、メインディレクトリは空であると言えます。それ以外の場合は空ではありません。
これをどのようにテストできますか?
例えば:
A>A1(file1),A2 this is not empty beacuse of file1
B>B1(no file) this is empty
C>C1,C2 this is empty
与えられたディレクトリのリストに対して空のディレクトリを見つける必要があります。一部のディレクトリには、その中にディレクトリがあります。
内部ディレクトリも空の場合、メインディレクトリは空であると言えます。それ以外の場合は空ではありません。
これをどのようにテストできますか?
例えば:
A>A1(file1),A2 this is not empty beacuse of file1
B>B1(no file) this is empty
C>C1,C2 this is empty
回答:
がfind <dir> -type f
何かを出力するかどうかを確認します。次に例を示します。
for dir in A B C; do
[ -z "`find $dir -type f`" ] && echo "$dir is empty"
done
-type f
が目的です。
mkdir A B C A/A1 A/A2 B/B1 C/C1 C/C2; touch A/A1/file1
し、返答のコードを実行すると、OPの必要に応じてBとCが空であると報告されます。したがって、「うまくいかない」よりも少し具体的にする必要があります。
空のディレクトリで何をしたいかによります。ツリー内のすべての空のディレクトリ、たとえばディレクトリを削除したい場合は、以下のコマンドを使用しますtest
。
find test -depth -empty -delete
上記のコマンドで気づくのは、空のファイルも削除されることです。そのため、-type dオプションを使用してそれを回避してください。
find test -depth -type d -empty -delete
ドロップ-delete
して、一致するファイルとディレクトリを確認します。
空のディレクトリツリーの定義にファイルが含まれていない場合、何かfind test -type f
が返されるかどうかに基づいて何かをくっつけることができます。
find
優れたユーティリティであり、RTFMは早期に、そして多くの場合、それが何をできるかを本当に理解するために:-)
-empty
ので、とても便利です!
find test -name ".DS_Store" -delete
最初に実行し、次に-empty delete
コマンドを実行します。またpushd
、親ディレクトリに似ているので、にfind test
なりfind .
ますが、残りのコマンドは同じです。
-depth
ここに定義を追加してください。つまり、 findが深さ優先のトラバーサルを実行するようにします。つまり、ディレクトリはポストオーダーでアクセスされ、ディレクトリ内のすべてのエントリはディレクトリ自体の前に作用します。ここでも関係があると思います。
次のコマンドを使用できます。
find . -type d -empty
find directory -mindepth 1 -type d -empty -delete
これは私が最も興味深いと思ったバージョンです。directoryの内部から実行すると、以下の空のディレクトリがすべて削除されます(空のディレクトリのみが含まれている場合、そのディレクトリは空と見なされます)。
mindepthオプションは、ディレクトリが空の場合でも削除されないようにします。
rmdir --ignore-fail-on-non-empty -p directory
て、親を取り除くこともできます。
find . -type d -empty
現在のツリーで空のディレクトリとサブディレクトリを見つけてリストします。たとえば、空のディレクトリとサブディレクトリの結果のリスト:
./2047
./2032
./2049
./2063
./NRCP26LUCcct1/2039
./NRCP26LUCcct1/2054
./NRCP26LUCcct1/2075
./NRCP26LUCcct1/2070
ディレクトリに対する操作は行われません。それらは単にリストされています。これでうまくいきます。
空のディレクトリ(質問のタイトルで指定)を見つけるだけの場合、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つの異なるテクニックを提供します。
[ $(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
(( ${#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
注:空のディレクトリと存在しないディレクトリの違いはありません(提供されたパスがファイルの場合でも)。
[ $(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
ルートの下にあるすべての空のディレクトリを削除するだけでなく、ファイルを削除した後に空のディレクトリと親ディレクトリを確認する必要があったので、非常に役に立ちました。私の状況では、現在ファイルを削除しているツリーにない限り、空のディレクトリは問題ありません。ありがとう!
この再帰関数はトリックを行うように見えます:
# 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
と、関数はそのディレクトリを結果に含めます。
いかがrmdir *
ですか?このコマンドは、空でないディレクトリでは失敗します。
rmdir */*/* */* *
「ドットファイル」は処理しませんが、手動の状況(データファイルのクリーニング)では、通常「ドットファイル」は期待していません。ただし、再帰的な方法は、特に非常に大きなディレクトリ構造で、より自動化された一般的なクリーンアップ用です。
次のコマンドは、ディレクトリが空の場合(または存在しない場合)は1を返し、それ以外の場合は0を返します(!
シェルスクリプトでリターンコードを反転させることができます)。
find $dir -type d -prune -empty -exec false {} +
次のように単純な構造を作成しました。
test/
test/test2/
test/test2/test2.2/
test/test3/
test/test3/file
にtest/test3/file
は、ジャンクテキストが含まれています。
発行find test -empty
するtest/test2/test2.2
と、唯一の空のディレクトリとして「」が返されます。