空のディレクトリやファイルのないディレクトリを繰り返し探します。

空のディレクトリやファイルのないディレクトリを繰り返し探します。

コマンドはありますが、find . -type d -empty文字通り空のディレクトリのみを見つけることができます。

私が達成したいのは少し複雑です。空のディレクトリまたは他のディレクトリのみを持つディレクトリまたは空のディレクトリを探したい場合は、この規則を再帰的に渡す必要があります。

たとえば、このディレクトリ構造は次を探します。ただし、~1/11/111/ ツリー1/内の任意の場所にファイルがある場合(たとえば、この場合)、ファイルがある場合はそのファイルより前のファイルを返すべきではありません。それ。したがって、隣に空のディレクトリがある場合は、1111を返す必要があります。1/11/1/11/111/1/11/111/file11/11/111/1111/1/11/111/file1

私がこれをしたいのは、空のフォルダを削除したいからです。

今度は繰り返し実行してこれを行うことができますが、find . -type d -empty -delete削除する前に可視化する方法が必要です。

可能ですか?

答え1

削除されたディレクトリを表示するには、以下を挿入してください-print

find . -type d -empty -print -delete

削除されたディレクトリのパス名を表示しながら、現在の空のディレクトリの下のすべてのサブレイヤを削除します。

これ-deleteは、-depthナビゲーションがディレクトリ構造の一番下から始まり上向きに進むことを意味します(深さ優先ナビゲーション)。これは、削除対象と見なすことができるすべてのディレクトリのサブディレクトリがすでに処理されていることを意味します(空の場合、そのサブディレクトリは削除されます)。

例:

$ mkdir -p 1/2/3/4/5/6
$ tree
.
`-- 1
    `-- 2
        `-- 3
            `-- 4
                `-- 5
                    `-- 6

6 directories, 0 file
$ find . -type d -empty -print -delete
./1/2/3/4/5/6
./1/2/3/4/5
./1/2/3/4
./1/2/3
./1/2
./1
$ tree
.

0 directory, 0 file

ディレクトリにファイルがある場合:

$ mkdir -p 1/2/3/4/5/6
$ touch 1/2/3/file
$ tree
.
`-- 1
    `-- 2
        `-- 3
            |-- 4
            |   `-- 5
            |       `-- 6
            `-- file

6 directories, 1 file
$ find . -type d -empty -print -delete
./1/2/3/4/5/6
./1/2/3/4/5
./1/2/3/4
$ tree
.
`-- 1
    `-- 2
        `-- 3
            `-- file

3 directories, 1 file

削除せずにサブディレクトリのみを含むディレクトリを一覧表示します(使用bash)。

shopt -s globstar
for dir in ./**/; do
    if [ -z "$(find "$dir" ! -type d -exec echo x \;)" ]; then
        printf '%s\n' "$dir"
    fi
done

これは、現在のディレクトリのすべてのサブディレクトリを繰り返し(**シェルグローブを使用して)、ディレクトリではなくサブディレクトリの1つの内容を見つけることを試みます。何かが見つかるとディレクトリは空ではなく、それ以外の場合は空のディレクトリのパス名が出力されます。

GNUを使用すると、上記のコマンドの最後(後半)にfind追加して作業を高速化できます。-quitfind\;

答え2

ディレクトリを削除せずに空のディレクトリを印刷するには、葉から上に空のディレクトリを削除する以外の作業を実行する必要があります。

次のように動作します。

find dir/ -type d ! -exec sh -c \
  'find "$1" ! -type d -print -quit | grep -q . >/dev/null' sh {} \; -print

外部から各ディレクトリを見つけてfind実行します。その他 findそれらのそれぞれに。findディレクトリに非ディレクトリエントリが含まれているか(繰り返し)内部的にチェックされ、含まれている場合はtrueを返します。次に、findfalseを返す各ディレクトリ(つまり、ディレクトリではなくディレクトリを含まない)を外部に印刷します。

しかし、find再帰的sの場合、これはかなり遅いです。より良い解決策には、ファイルを含むディレクトリをキャッシュするか、空のディレクトリから始めてファイルを含むブランチまで作業する方法を含めることができます。

関連情報