it-swarm.it

Come posso contare tutti i file in modo ricorsivo attraverso le directory

Voglio vedere quanti file sono nelle sottodirectory per scoprire dove si trova tutto l'utilizzo dell'inode sul sistema. Un po 'come farei per l'uso dello spazio

du -sh /*

che mi darà lo spazio utilizzato nelle directory al di fuori di root, ma in questo caso voglio il numero di file, non la dimensione.

52
xenoterracide
find -maxdepth 1 -type d | while read -r dir; do printf "%s:\t" "$dir"; find "$dir" -type f | wc -l; done

Grazie a Gilles e xenoterracide per le correzioni di sicurezza/compatibilità.

La prima parte: find -maxdepth 1 -type d restituirà un elenco di tutte le directory nella directory di lavoro corrente. Questo è indirizzato a ...

La seconda parte: while read -r dir; do inizia un ciclo while - fintanto che la pipe che entra nel while è aperta (ovvero fino a quando non viene inviato l'intero elenco di directory), il comando read inserirà la riga successiva nella variabile "dir". Quindi continua ...

La terza parte: printf "%s:\t" "$dir"; stamperà la stringa in "$ dir" (che contiene uno dei nomi di directory) seguito da una scheda.

La quarta parte: find "$dir -f file" crea un elenco di tutti i file all'interno del nome della directory contenuti in "$ dir". Questo elenco viene inviato a ..

La quinta parte: wc -l; conta il numero di righe che vengono inviate nel suo input standard.

La parte finale: done termina semplicemente il ciclo while.

Quindi otteniamo un elenco di tutte le directory nella directory corrente. Per ognuna di quelle directory, generiamo un elenco di tutti i file in essa contenuti in modo da poterli contare tutti usando wc -l. Il risultato sarà simile a:

./dir1: 234
./dir2: 11
./dir3: 2199
...
67
Shawn J. Goff

Provare find . -type f | wc -l, conterà tutti i file nella directory corrente e tutti i file nelle sottodirectory. Si noti che tutte le directory non verranno conteggiate come file, ma solo i file ordinari.

17
herohuyongtao

Ecco una raccolta di alcuni utili comandi di elenco (rielaborati in base al codice degli utenti precedenti):

Elenca le cartelle con il conteggio dei file:

find -maxdepth 1 -type d | sort | while read -r dir; do n=$(find "$dir" -type f | wc -l); printf "%4d : %s\n" $n "$dir"; done

Elenca le cartelle con un numero di file diverso da zero:

find -maxdepth 1 -type d | sort | while read -r dir; do n=$(find "$dir" -type f | wc -l); if [ $n -gt 0 ]; then printf "%4d : %s\n" $n "$dir"; fi; done

Elenca le cartelle con il conteggio delle sottocartelle:

find -maxdepth 1 -type d | sort | while read -r dir; do n=$(find "$dir" -type d | wc -l); let n--; printf "%4d : %s\n" $n "$dir"; done

Elenca le cartelle con un conteggio di sottocartelle diverso da zero:

find -maxdepth 1 -type d | sort | while read -r dir; do n=$(find "$dir" -type d | wc -l); let n--; if [ $n -gt 0 ]; then printf "%4d : %s\n" $n "$dir"; fi; done

Elenca cartelle vuote:

find -maxdepth 1 -type d | sort | while read -r dir; do n=$(find "$dir" | wc -l); let n--; if [ $n -eq 0 ]; then printf "%4d : %s\n" $n "$dir"; fi; done

Elenca le cartelle non vuote con il conteggio dei contenuti:

find -maxdepth 1 -type d | sort | while read -r dir; do n=$(find "$dir" | wc -l); let n--; if [ $n -gt 0 ]; then printf "%4d : %s\n" $n "$dir"; fi; done
13
DolphinDream

Provare:

find /path/to/start/at -type f -print | wc -l

come punto di partenza o se si desidera veramente solo ricorrere alle sottodirectory di una directory (e saltare i file in quella directory di livello superiore)

find `find /path/to/start/at -mindepth 1 -maxdepth 1 -type d -print` -type f -print | wc -l
12
Cry Havok

La seguente soluzione conta il numero effettivo di inode utilizzati a partire dalla directory corrente:

find . -print0 | xargs -0 -n 1 ls -id | cut -d' ' -f1 | sort -u | wc -l

Per ottenere il numero di file dello stesso sottoinsieme, utilizzare:

find . | wc -l

Per soluzioni che esplorano solo le sottodirectory, senza tenere conto dei file nella directory corrente, è possibile fare riferimento ad altre risposte.

4
mouviciel

OS X 10.6 soffoca il comando nella risposta accettata, perché non specifica un percorso per find. Invece usa:

find . -maxdepth 1 -type d | while read -r dir; do printf "%s:\t" "$dir"; find "$dir" -type f | wc -l; done
2
abeboparebop

So di essere in ritardo alla festa, ma credo che questa pura soluzione bash (o altra Shell che accetta il doppio stella globale) potrebbe essere molto più veloce in alcune situazioni:

shopt -s globstar    # to enable ** glob in bash
for dir in */; do a=( "$dir"/**/* ); printf "%s\t%s\n" "$dir:" "${#a[*]}"; done

produzione:

d1/:    302
d2/:    24
d3/:    640
...
2
jimmij

Prova questo:

find -type d -print0 | xargs -0 -I {} sh -c 'printf "%s\t%s\n" "$(find "{}" -maxdepth 1 -type f | wc -l)" "{}"'

Dovrebbe funzionare bene a meno che i nomi dei file includano le nuove righe.

du --inodes

Non sono sicuro del motivo per cui nessuno (me compreso) era a conoscenza di:

du --inodes
--inodes
      list inode usage information instead of block usage

Sono abbastanza sicuro che questo risolva il problema del PO. Ho iniziato a usarlo molto per scoprire dove si trova tutta la spazzatura nelle mie enormi unità (e scaricarla su un disco più vecchio).

Ulteriori informazioni

Se NON vuoi ricorrere (che può essere utile in altre situazioni), aggiungi

-S, --separate-dirs
1
Sridhar Sarnobat

Se hai installato ncdu (un must quando vuoi fare un po 'di pulizia), digita semplicemente c in "Attiva/disattiva visualizzazione conteggi elementi figlio". E C su "Ordina per elementi".

1
Demi-Lune