ファイルを含むリーフ ディレクトリのみを見つけるには、参照されている質問 https://unix.stackexchange.com/a/203991/330217 または同様の質問 https://stackoverflow.com/a/4269862/10622916 の回答を組み合わせることができます。または https://serverfault.com/a/530328 with find
の ! -empty
find rootdir -type d -links 2 ! -empty
-links 2
でハードリンクをチェックする 従来の UNIX ファイル システムで動作するはずです。 -empty
condition は POSIX 標準の一部ではありませんが、ほとんどの Linux システムで利用できるはずです。
KamilMaciorowski のコメントによると、ディレクトリの従来のリンク カウント セマンティクスは Btrfs には有効ではありません。これは https://linux-btrfs.vger.kernel.narkive.com/oAoDX89D/btrfs-st-nlink-for-directories で確認されており、従来の動作の例外として Mac OS HFS+ についても言及されています。これらのファイル システムでは、リーフ ディレクトリをチェックする別の方法が必要です。
ネストされた find
を使用できます サブディレクトリの数を数えます:
find . -type d \
\( -exec sh -c 'find "$1" -mindepth 1 -maxdepth 1 -type d -print0 | grep -cz "^" >/dev/null 2>&1' _ {} \; -o -print \)
*/
の場合 ファイル名のグロビング パターンがディレクトリの名前ではないものに展開された場合、現在のディレクトリには (隠されていない) サブディレクトリはありません。
find
で :
find root -type d -exec sh -c 'set -- "$1"/*/; [ ! -d "$1" ]' sh {} \; ! -empty -print
パターンがシンボリック リンクをトラバースするため、これはリーフ ディレクトリ内のディレクトリへのシンボリック リンクをディレクトリとして扱うことに注意してください。
-empty
predicate は標準ではありませんが、実装されることがよくあります。それがなければ、サブディレクトリの検出と同様のことを行うことになります:
find root -type d \
-exec sh -c 'set -- "$1"/*/; [ ! -d "$1" ]' sh {} \; \
-exec sh -c 'set -- "$1"/*; [ -e "$1" ]' sh {} \; -print
または、もう少し効率的に
find root -type d -exec sh -c '
dir=$1
set -- "$dir"/*/
[ -d "$1" ] && exit 1
set -- "$dir"/*
[ -e "$1" ]' sh {} \; -print
または、 -links
を採用 私が忘れていた述語 (Bodo に感謝):
find root -type d \
-links 2 \
-exec sh -c 'set -- "$1"/*; [ -e "$1" ]' sh {} \; -print