空のディレクトリを再帰的に検索

空のディレクトリを再帰的に検索

たとえば、/home/.../Desktopですべての空のディレクトリを見つける方法は?私はSolarisを使用しているため、このコマンドは使用できませんfind . -empty -type d。別の方法がありますか?

答え1

(私は便利なSolarisシステムがないため、マンページを使用しているので、ここで構文を少し扱う必要があるかもしれません。)

ディレクトリが(単一の)ディレクトリエントリに追加されない限り、UNIXでは空のdirディレクトリへのリンク数が2であるという事実を利用できます。dir/.ディレクトリエントリがここに追加されます。それ以外の場合は、ディレクトリへの(ハード)リンクが違法であるため、これは不変です。 (基本的に1.

この-emptyオプションはSolarisではサポートされていませんが、する-links <n>正確なモノ検索をサポートするオプションNリンク。だからあなたが望むコマンドは(私は考える;下記参照)は以下の通りである。

find /home/.../Desktop -type d -links 2 -print

しかし…

「再帰的に」という言葉を使うのは少しあいまいです。したがって、空のディレクトリのみを含むディレクトリは検索されません(または再帰的に)。必要に応じて、順番に識別したい場合は問題は簡単です削除。上記のコマンドを繰り返し実行し、それ-exec rmdir {} \;以上コマンドがなくなるまで追加すると、ツリーの1つ以上の深い親エントリが削除されるため、そのコマンドがない場合は複数回実行する必要はありません。非常に深いディレクトリツリーは空のディレクトリでのみ構成されます。 (Solarisの使用方法に応じて検索(1)動作します。一度しか実行できないようですfind . -type d -exec rmdir -p {};-pオプションで目次(1)空のディレクトリを含むディレクトリを削除することはできますが、削除されたディレクトリを繰り返すことを試みるため、無視できる可能性のある複数のエラーメッセージが興味のあるエラーメッセージと混在して表示されるため、そうします。代わりにこれを繰り返し実行します。 )

-depth(このオプションは参考にしてください。検索(1)ファイルがあるので、ここでは役に立ちません。統計()リンク数を更新するには早すぎます。それ以外の場合は実行でき、find -depth $dir -type d -links 2 -exec rmdir {} \;一度だけ実行すれば十分です。 )

識別したい場合両方「本質的に空の」ディレクトリと削除せずに空のディレクトリのみ(または再帰的)を含むディレクトリの場合は、より複雑です。私は単一のコマンドラインが可能だと思いますが、少なくともperl狂気sedawk呪文に頼らずにそれは獣になります(後で他の人がそれを試すと確信しています)。

しかし、私がしたいのは、ディレクトリツリーをどこかにコピーすることです。/tmp/ツリーコピー, 次にコマンドを実行します。

find /tmp/tree-copy -type d -links 2 -print -exec rmdir {} \; | tee -a /tmp/empty-dirlist

出力が生成されなくなるまで繰り返します。 (tee -a出力を表示してファイルに追加することもできます。/tmp/空のディレクトリ一覧.)

/tmp/tree-copy次に、ファイルの各行から何かを削除する必要があります。

perl -i -lpe 's{^/tmp/tree-copy/}{}' /tmp/empty-dirlist

これには機能するか、テキストエディタを使用できます。望むより!、「Bean」は、「ディレクトリのみを含む」と定義されている空のディレクトリのリストです。 (必要に応じてパイプに入れる前にperl、または、または他のものを入れることもできます。)sedtee -a


  1. 一部の人がこれを指摘する前に、これはファイルシステムに必ずしも当てはまるわけではありません。マウントポイント;一部のオペレーティングシステムのファイルシステム管理者は、自分の個人的な目的のためにマウントポイントのリンク数を自由に使用できるため、空であっても、リンク数が1(そうでなければ違法な)マウントポイントディレクトリを頻繁に表示できます。ディレクトリの場合)2または意味がありますが、実際のリンク数とは何の関係もありません。したがって、上記の作業を行う場合は、マウントポイントを通過する可能性があることを確認する必要があります。可能性は低いですが、マウントポイントの1つのリンク数が2である可能性があるためです。

答え2

ギイ;

find . -type d -links 2 -exec sh -c '
    is_empty () (
        cd "$1"
        set -- .[!.]* ; test -f "$1" && return 1
        set -- ..?* ; test -f "$1" && return 1
        set -- * ; test -f "$1" && return 1
        return 0
    )
    is_empty "$0" ' {} \; -print

説明する

-type d-links 2最初は、結果を「リーフ」ディレクトリ、つまり実際には空またはファイルのみを含むディレクトリに制限するオプションと連携します。空のディレクトリのみを考慮するには、さらにいくつかのことが必要です。

この目的で一般的に使用されるオプションは、-emptyPOSIXではなく拡張です。この欠点を克服するために借りたRichのsh(POSIXシェル)トリック。この-exec sh -c'...'イディオムは私がいつも避ける表現ですが、まだ良い選択肢を見つけることができませんでした。

引用する

関連情報