contare il numero di directory in una directory specifica


103

Come contare il numero di cartelle in una directory specifica. Sto usando il seguente comando, ma ne fornisce sempre uno extra.

find /directory/ -maxdepth 1 -type d -print| wc -l

Ad esempio, se ho 3 cartelle, questo comando ne fornisce 4. Se contiene 5 cartelle, il comando fornisce 6. Perché?


4
Il conteggio 1 aggiuntivo è dovuto alla directory corrente "." , che viene preso in considerazione anche da "find".
patel deven

Risposte:


94

find sta anche stampando la directory stessa:

$ find .vim/ -maxdepth 1 -type d
.vim/
.vim/indent
.vim/colors
.vim/doc
.vim/after
.vim/autoload
.vim/compiler
.vim/plugin
.vim/syntax
.vim/ftplugin
.vim/bundle
.vim/ftdetect

Puoi invece testare i figli della directory e non discenderli affatto:

$ find .vim/* -maxdepth 0 -type d
.vim/after
.vim/autoload
.vim/bundle
.vim/colors
.vim/compiler
.vim/doc
.vim/ftdetect
.vim/ftplugin
.vim/indent
.vim/plugin
.vim/syntax

$ find .vim/* -maxdepth 0 -type d | wc -l
11
$ find .vim/ -maxdepth 1 -type d | wc -l
12

Puoi anche usare ls:

$ ls -l .vim | grep -c ^d
11


$ ls -l .vim
total 52
drwxrwxr-x  3 anossovp anossovp 4096 Aug 29  2012 after
drwxrwxr-x  2 anossovp anossovp 4096 Aug 29  2012 autoload
drwxrwxr-x 13 anossovp anossovp 4096 Aug 29  2012 bundle
drwxrwxr-x  2 anossovp anossovp 4096 Aug 29  2012 colors
drwxrwxr-x  2 anossovp anossovp 4096 Aug 29  2012 compiler
drwxrwxr-x  2 anossovp anossovp 4096 Aug 29  2012 doc
-rw-rw-r--  1 anossovp anossovp   48 Aug 29  2012 filetype.vim
drwxrwxr-x  2 anossovp anossovp 4096 Aug 29  2012 ftdetect
drwxrwxr-x  2 anossovp anossovp 4096 Aug 29  2012 ftplugin
drwxrwxr-x  2 anossovp anossovp 4096 Aug 29  2012 indent
drwxrwxr-x  2 anossovp anossovp 4096 Aug 29  2012 plugin
-rw-rw-r--  1 anossovp anossovp 2505 Aug 29  2012 README.rst
drwxrwxr-x  2 anossovp anossovp 4096 Aug 29  2012 syntax

$ ls -l .vim | grep ^d
drwxrwxr-x  3 anossovp anossovp 4096 Aug 29  2012 after
drwxrwxr-x  2 anossovp anossovp 4096 Aug 29  2012 autoload
drwxrwxr-x 13 anossovp anossovp 4096 Aug 29  2012 bundle
drwxrwxr-x  2 anossovp anossovp 4096 Aug 29  2012 colors
drwxrwxr-x  2 anossovp anossovp 4096 Aug 29  2012 compiler
drwxrwxr-x  2 anossovp anossovp 4096 Aug 29  2012 doc
drwxrwxr-x  2 anossovp anossovp 4096 Aug 29  2012 ftdetect
drwxrwxr-x  2 anossovp anossovp 4096 Aug 29  2012 ftplugin
drwxrwxr-x  2 anossovp anossovp 4096 Aug 29  2012 indent
drwxrwxr-x  2 anossovp anossovp 4096 Aug 29  2012 plugin
drwxrwxr-x  2 anossovp anossovp 4096 Aug 29  2012 syntax

Bello! Come lo faresti $ ls -l .vimcon PHP? O come ottenere solo il totale, senza l'elenco. Voglio dire, in questo caso ottieni solo 52?
Pathros

Hah. Adoro il modo in cui l'argomento contro PowerShell è che BASH è più facile in ogni modo ... vuoi vedere il comando POSH per farlo? (ls).Count
Kolob Canyon,

@ Pathros Usa glob con flag GLOB_ONLYDIR e count () il risultato.
Pilipe

1
ls -l | grep -c ^dè semplicissimo e funziona. @ Pathros c'è probabilmente un modo migliore in PHP, ma nel peggiore dei casi in PHP puoi sempre usare la funzione shell_exec () per eseguire la riga di comando e restituire i risultati a una stringa. cioè $dirCount = shell_exec('ls -l | grep -c ^d');
gigabyte

66

Ottieni un conteggio delle sole directory nella directory corrente

echo */ | wc

uscirai come 1 309 4594

2nd digitrappresenta no. di directory.

o

tree -L 1 | tail -1


8
Questo fallisce se ci sono spazi nei nomi delle directory, sfortunatamente.
Michael Campbell

zsh: no matches found: */necessita di nullglob
Anne van Rossum

@AnnevanRossum Ce l'hai echo. tipowhich echo
EmptyData

7
Il primo può essere ulteriormente migliorato un po ':echo */ | wc -w
ibic

Nota che questo conterà 1 se non ci sono directory invece di 0.
jinawee

27
find . -mindepth 1 -maxdepth 1 -type d | wc -l

Per trovare -mindepthindica il numero totale recusivo nelle directory

-maxdepth significa numero totale recusivo nelle directory

-type d significa directory

E per wc -lmezzo conta le righe dell'input


2
Puoi spiegare la tua risposta per favore (all'interno della tua risposta)?
Zulu

-mindepth significa numero totale recusivo nelle directory, -maxdepth significa numero totale recusivo nelle directory, -type d significa directory e wc -l significa numero di righe dall'elenco di directory specificato
shiyani suresh

find . -mindepth 1 -maxdepth 1 -type d | wc -lti darà molti spazi tra il numero, ad esempio: ` dir_count=`find . -maxdepth 1 -type d | wc -l | xargs`; echo $dir_count # will print just 2 if (( $dir_count > 1 )); then echo "Yaa"; fi # will print "Yaa"
2`

16

Se hai solo directory nella cartella e nessun file questo lo fa:

ls | wc -l

2
Questo ottiene anche i file, ma la domanda riguardava le cartelle / directory.
Robert

12

Il modo migliore per navigare verso l'unità ed eseguire semplicemente

ls -lR | grep ^d | wc -l

e per trovare tutte le cartelle in totale, comprese le sottodirectory?

find /mount/point -type d | wc -l

... o trovare tutte le cartelle nella directory principale (escluse le sottodirectory)?

find /mount/point -maxdepth 1 -type d | wc -l

Saluti!


Nota che i precedenti ls -lRignorano la directory con il punto prefisso mentre li find -type d contano, quindi il conteggio dato dal primo comando è sbagliato se hai directory con il punto prefisso (ad esempio hai la sottodirectory .git!). Non puoi semplicemente usare -lRaperché ottieni anche per ogni directory una voce .e ... Si applica anche alla risposta di @Pavel Anossov
marcz

12

Corri stat -c %h foldere sottrai 2 dal risultato. Questo impiega solo un singolo sottoprocesso in contrasto con il 2 (o anche 3) richiesto dalla maggior parte delle altre soluzioni qui (tipicamente findpiù wc).

Utilizzando sh / bash:

cnt = $ ((`stat -c% h cartella` - 2))
echo $ cnt # 'echo' è un builtin sh / bash, non un processo aggiuntivo

Utilizzando csh / tcsh:

@ cnt = `stat -c% h folder` - 2
echo $ cnt # 'echo' è un builtin di csh / tcsh, non un processo aggiuntivo


Spiegazione: stat -c %h folderstampa il numero di collegamenti fisici alla cartella e ogni sottocartella nella cartella contiene una voce ../ che è un collegamento fisico alla cartella . Devi sottrarre 2 perché ci sono due collegamenti fisici aggiuntivi nel conteggio:

  1. la voce ./ autoreferenziale della cartella e
  2. cartella di collegamento con i genitori 's alla cartella

In relazione a questa domanda: [Perché una nuova directory ha un conteggio di collegamenti reali pari a 2 prima che venga aggiunto qualcosa? ] ( unix.stackexchange.com/questions/101515 ) Spiega perché questa è un'ottima risposta. Sfortunatamente, questo non ha ricevuto abbastanza attenzione! Sebbene sia una buona risposta, il risultato dipende sfortunatamente dal filesystem, ma per i filesystem più comuni, funzionerà.
kvantour

8

Penso che il più semplice sia

  ls -ld images/* | wc -l

dov'è la imagestua directory di destinazione. Il flag -d limita le directory e il flag -l eseguirà un elenco per riga, compatibile con il più familiare wc -lper il conteggio delle righe.


Restituisce anche il risultato +1
josef

1
Secondo man ls, -ddoes: "elenca le directory stesse, non il loro contenuto", cioè, se corri ls /tmp, otterrai ciò che è dentro /tmp, e se corri ls -d /tmpottieni /tmp. Lo -dswitch non filtra le directory, come richiesto.
Robert

5

Alcuni esempi utili:

conta i file nella directory corrente

/bin/ls -lA  | egrep -c '^-'

conta le directory nella directory corrente

/bin/ls -lA  | egrep -c '^d'

conta file e directory nella directory corrente

/bin/ls -lA  | egrep -c '^-|^d'

conta file e directory in una sottodirectory

/bin/ls -lA  subdir_name/ | egrep -c '^-|^d'

Ho notato una cosa strana (almeno nel mio caso):

Quando ho provato con lsinvece /bin/ls il -Aparametro do not list implied . and ..NON FUNZIONA come previsto. Quando uso lsquello spettacolo ./ e ../ Quindi il risultato sbagliato conta. SOLUZIONE: /bin/lsinvecels


4

Nessuna directory che possiamo trovare utilizzando il comando seguente

ls -l | grep "^d" | wc -l


Basta ls -l | grep ^d | wc -l, non c'è bisogno di usare "qui
kaspiotr

3

Una soluzione bash pura:

shopt -s nullglob
dirs=( /path/to/directory/*/ )
echo "There are ${#dirs[@]} (non-hidden) directories"

Se vuoi contare anche le directory nascoste:

shopt -s nullglob dotglob
dirs=( /path/to/directory/*/ )
echo "There are ${#dirs[@]} directories (including hidden ones)"

Nota che questo conterà anche i collegamenti alle directory. Se non lo vuoi, è un po 'più difficile con questo metodo.


Utilizzando find:

find /path/to/directory -type d \! -name . -prune -exec printf x \; | wc -c

Il trucco sta nell'output di un xa stdout ogni volta che viene trovata una directory, e quindi utilizzare wcper contare il numero di caratteri. Questo conterà il numero di tutte le directory (comprese quelle nascoste), esclusi i collegamenti.


I metodi qui presentati sono tutti sicuri rispetto a caratteri divertenti che possono apparire nei nomi di file (spazi, caratteri di fine riga, caratteri glob, ecc.).


Questa è la migliore soluzione presentata in questa domanda e funzionerà sempre!
kvantour

3

Utilizzando zsh:

a=(*(/N)); echo ${#a}

Il Nè un nullglob, /rende corrisponde directory, #i conteggi. Gestirà perfettamente gli spazi nei nomi delle directory e restituirà 0se non ci sono directory.


0

Contare tutti i file e le sottocartelle, in stile Windows:

dir=/YOUR/PATH;f=$(find $dir -type f | wc -l); d=$(find $dir -mindepth 1 -type d | wc -l); echo "$f Files, $d Folders"

0

Se desideri utilizzare espressioni regolari, prova:

ls -c | grep "^d" | wc -l

1
Vorresti aggiungere qualche spiegazione alla tua risposta solo in codice? Aiuterebbe a combattere il malinteso secondo cui StackOverflow è un servizio di scrittura di codice gratuito. Inoltre, date un'occhiata qui per migliorare l'aspetto: stackoverflow.com/editing-help
Yunnosch

0

La migliore risposta a quello che vuoi è

echo `find . -maxdepth 1 -type d | wc -l`-1 | bc

questo sottrae uno per rimuovere il "." directory che trova elenchi (come patel deven menzionato sopra).

Se vuoi contare le sottocartelle in modo ricorsivo, lascia semplicemente fuori l'opzione maxdepth, quindi

echo `find . -type d | wc -l`-1 | bc

PS Se trovi brutta la sostituzione dei comandi, la sottrazione di una può essere eseguita come un flusso puro usando sede bc.

Sottraendo uno dal conteggio:

find . -maxdepth 1 -type d | wc -l | sed 's/$/-1\n/' | bc

oppure, aggiungendo count a meno uno:

find . -maxdepth 1 -type d | wc -l | sed 's/^/-1+/' | bc

-1

Il modo migliore per farlo:

ls -la | grep -v total | wc -l

Questo ti dà il conteggio perfetto.


6
Vuoi dire che è il modo peggiore per farlo! inoltre, questo non conta il numero di directory. E se c'è un nome di directory che contiene la stringa total? il tuo metodo è rotto :(. Non analizzarels !
gniourf_gniourf
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.