web-dev-qa-db-ja.com

GNU findを使用して、リーフディレクトリのみを表示します

GNU findを使用して、他のディレクトリを含まないディレクトリのみを検索しますが、通常のファイルが含まれている場合と含まれていない場合があります。

これまでのところ、私の最良の推測は次のとおりです。

find dir -type d \( -not -exec ls -dA ';' \)

しかし、これは "。"の長いリストを取得するだけです。

ありがとう!

44
Thomas G Henry

ファイルシステムがPOSIXに準拠している場合(つまり、ディレクトリに各サブディレクトリへのリンク、親からのリンク、および自己へのリンクがあるため、サブディレクトリがない場合は2リンクとしてカウントされます)、-linksを使用できます。

次のコマンドはあなたが望むことをするはずです:

find dir -type d -links 2

ただし、Mac OS Xでは機能しないようです(@Piotrが言及したとおり)。これは遅いバージョンですが、Mac OS Xでは動作します。これは彼のバージョンに基づいており、ディレクトリ名の空白を処理するように修正されています。

find . -type d -exec sh -c '(ls -p "{}"|grep />/dev/null)||echo "{}"' \;
83

LinuxとmacOSの両方で動作する別の解決策を見つけました(find -execなし)!

sort(2回)とawkが含まれます。

find dir -type d | sort -r | awk 'a!~"^"$0{a=$0;print}' | sort

説明:

  1. findの出力を逆順に並べ替える

    • これで、最初にサブディレクトリが表示され、次にその親が表示されます
  2. 現在の行が前の行の接頭辞である場合、awkを使用して行を省略します

    • (このコマンドは ここで回答 からのものです)
    • ここで「すべての親ディレクトリ」を削除しました(親ディレクトリが残っています)
  3. sortそれら(通常のfind出力のように見える)
  4. 出来上がり!高速でポータブル。
5
AhmetB - Google

@Sylvianソリューションは、何らかの理由でmac os xで動作しませんでした。そこで、もう少し直接的な解決策を考えました。これが誰かを助けることを願っています:

find . -type d  -print0 | xargs -0 -IXXX sh -c '(ls -p XXX | grep / >/dev/null) || echo XXX' ;

説明:

  • ls -pは「/」でディレクトリを終了します
  • そう (ls -p XXX | grep / >/dev/null)ディレクトリがない場合は0を返します
  • -print0 && -0は、xargsにディレクトリ名のスペースを処理させる
2
Piotr Czapla

LinuxとOS Xで動作するソリューションは次のとおりです。

find . -type d -execdir bash -c '[ "$(find {} -mindepth 1 -type d)" ] || echo $PWD/{}' \; 

または:

find . -type d -execdir sh -c 'test -z "$(find "{}" -mindepth 1 -type d)" && echo $PWD/{}' \;
0
kenorb

これはどうですか ?移植性があり、finnickyのリンク数に依存しません。ただし、root/folderなしの後に/を付けることが重要です。

find root/folder -type d | awk '{ if (length($0)<length(prev) || substr($0,1,length(prev))!=prev) print prev; prev=($0 "/") } END { print prev }'
0
DREV

@AhmetAlpBalkanの回答のように、awkを混乱させるディレクトリツリーに奇妙な名前のファイルがいくつかあります。だから私は少し異なるアプローチをとりました

  p=;
  while read c;
    do 
      l=${#c};
      f=${p:0:$l};
      if [ "$f" != "$c" ]; then 
        echo $c; 
      fi;
      p=$c; 
    done < <(find . -type d | sort -r) 

awkソリューションと同様に、逆のソートを行います。これにより、ディレクトリパスが以前のヒットのサブパスである場合、これを簡単に識別できます。

ここで、pは以前の一致、cは現在の一致、lは現在の一致の長さ、fは最初のl前の一致の一致する文字。私は前の試合の始まりと一致しないヒットのみをechoします。

提供されているawkソリューションの問題は、一部のサブディレクトリの名前にパス名に+などが含まれている場合、文字列の先頭のマッチングが混乱しているように見えることです。これにより、awkはいくつかの誤検知を返しました。

0
A.Ellett