ファイルのない最も浅いディレクトリのみを一覧表示します。

ファイルのない最も浅いディレクトリのみを一覧表示します。

次のファイルシステム構造を想定します。

ROOT
    DIR1A
        FILE
        DIR2A
        DIR2B
            DIR3A
    DIR1B
        DIR2C
        DIR2D
            DIR3B
    DIR1C
        DIR2E
            FILE

任意のディレクトリから始めて、空のサブディレクトリを一覧表示せずにa)何も含まない、またはb)空のディレクトリのみを含む最も浅いサブディレクトリのみを一覧表示するにはどうすればよいですか?

つまり、上記の場合、ROOTで始まると次のようになります。

  1. DIR1A にはファイルが含まれているため、リストされません。
  2. DIR2Aには何も含まれていないため、リストされています。
  3. DIR2Bには空のディレクトリのみが含まれているため、一覧表示されます。
  4. DIR3A はすでにリストされている浅いディレクトリにあるため、リストされません。
  5. DIR1Bには空のディレクトリのみが含まれているため、一覧表示されます。
  6. DIR1B のサブディレクトリは、すでにリストされている浅いディレクトリにあるため、リストされません。
  7. DIR1CまたはDIR2Eにはファイルがネストされているため、リストされません。

私はこれを表現するより効率的な方法があると思います。たぶん、「何も含まれていないか、空のディレクトリだけを含む最上位のディレクトリだけをリストしたいですか?」

編集:上記の言語の一部を明確にしようとしました。

ベストアンサー1

ディレクトリツリーをあまり探索しないで実行されるコマンドの数を最小限に抑えるには、次のようにします(GNUfindおよびsort同様のNULをエコー区切り文字awkとしてサポートしていると仮定)。RS

find . -type d -print0 -o -printf 'f/%h\0' |
  LC_ALL=C sort -zru |
  LC_ALL=C awk -F/ -vRS='\0' '
    function parent(path) {
      sub("/[^/]*$", "", path)
      return path
    }
    $1 == "f" {
      sep = path = ""
      for (i = 2; i <= NF; i++) {
        black[path = path sep $i]
        sep = FS
      }
      next
    }
    ! ($0 in black) && ($0 == "." || parent($0) in black)'

その下にディレクトリ以外のファイルを含むすべてのディレクトリを黒で塗りつぶし、黒の親を持つ(または特別な場合は親を持たない)黒ではない.ディレクトリを印刷します。

これらのディレクトリを削除することが目標である場合は、次のようにできます。

find . -depth -type d -empty -delete

-deleteを意味します-depthが、明確にするためにここに追加します(GNUのfindマニュアルで提案されているように)。-deleteいずれにせよ、空のディレクトリのみが削除されるため、空で-emptyないディレクトリを削除できないときに発生するエラーメッセージを回避できます。深さ優先を使用するdと、ディレクトリ以外のファイルを除く構造全体を削除し、葉がある分岐前の葉を削除します。

-deleteBSDとGNUの非標準的な拡張ですが、-emptyどちらも現在かなり一般的です。そのエントリがない場合は、いつでも次の2つを置き換えることができます(おそらく次のエラーメッセージを削除できます)。-delete-emptyfindfind-exec rmdir {} +2> /dev/nullみんなfindと)エラーメッセージrmdir

おすすめ記事