Per trovare solo quelle directory foglia che contengono file, puoi combinare una risposta alla domanda di riferimento https://unix.stackexchange.com/a/203991/330217 o domande simili https://stackoverflow.com/a/4269862/10622916 o https://serverfault.com/a/530328 con find
è ! -empty
find rootdir -type d -links 2 ! -empty
Controllo degli hard link con -links 2
dovrebbe funzionare per i file system UNIX tradizionali. Il -empty
condition non fa parte dello standard POSIX, ma dovrebbe essere disponibile sulla maggior parte dei sistemi Linux.
Secondo il commento di KamilMaciorowski, la tradizionale semantica del conteggio dei collegamenti per le directory non è valida per Btrfs. Ciò è confermato in https://linux-btrfs.vger.kernel.narkive.com/oAoDX89D/btrfs-st-nlink-for-directories che menziona anche Mac OS HFS+ come eccezione dal comportamento tradizionale. Per questi file system è necessario un metodo diverso per controllare le directory foglia.
Potresti usare find
nidificato e contare il numero di sottodirectory:
find . -type d \
\( -exec sh -c 'find "$1" -mindepth 1 -maxdepth 1 -type d -print0 | grep -cz "^" >/dev/null 2>&1' _ {} \; -o -print \)
Se il */
il modello di globbing del nome file si espande in qualcosa che non è il nome di una directory, quindi la directory corrente non ha sottodirectory (non nascoste).
Con find
:
find root -type d -exec sh -c 'set -- "$1"/*/; [ ! -d "$1" ]' sh {} \; ! -empty -print
Nota che questo tratterebbe un collegamento simbolico a una directory in una directory foglia come una directory poiché il modello attraverserebbe il collegamento simbolico.
Il -empty
predicato non è standard, ma spesso implementato. Senza di esso, faresti qualcosa di simile al rilevamento delle sottodirectory:
find root -type d \
-exec sh -c 'set -- "$1"/*/; [ ! -d "$1" ]' sh {} \; \
-exec sh -c 'set -- "$1"/*; [ -e "$1" ]' sh {} \; -print
Oppure, in modo un po' più efficiente,
find root -type d -exec sh -c '
dir=$1
set -- "$dir"/*/
[ -d "$1" ] && exit 1
set -- "$dir"/*
[ -e "$1" ]' sh {} \; -print
Oppure, utilizzando il -links
predicato di cui mi ero dimenticato (grazie Bodo):
find root -type d \
-links 2 \
-exec sh -c 'set -- "$1"/*; [ -e "$1" ]' sh {} \; -print