Qual è il modo migliore per contare i risultati "trova"?


97

La mia soluzione attuale sarebbe find <expr> -exec printf '.' \; | wc -c, ma questo richiede troppo tempo quando ci sono più di 10000 risultati. Non esiste un modo migliore / più veloce per farlo?


usa wc -l sui risultati della ricerca
Manuel Selva

Risposte:


82

Prova questo invece (richiede findil -printfsupporto di):

find <expr> -type f -printf '.' | wc -c

Sarà più affidabile e più veloce del conteggio delle linee.

Nota che uso find's printf, non un comando esterno.


Mettiamo un po 'in panchina:

$ ls -1
a
e
l
ll.sh
r
t
y
z

Il mio benchmark di snippet:

$ time find -type f -printf '.' | wc -c
8

real    0m0.004s
user    0m0.000s
sys     0m0.007s

Con righe complete:

$ time find -type f | wc -l
8

real    0m0.006s
user    0m0.003s
sys     0m0.000s

Quindi la mia soluzione è più veloce =) (la parte importante è la reallinea)


6
Non equivalente, è più affidabile =)
Gilles Quenot

6
Non è più affidabile se il flag -printf da trovare non è supportato sulla tua piattaforma. ;-)
Randy Howard

7
Nota che puoi raderti qualche nanosecondo in più non citando il punto in-printf '.'
Jens

6
@Jens - soprattutto quando si prende in considerazione il tempo necessario per digitare che
Brian Agnew

6
Con un benchmark così piccolo, i tempi sono probabilmente dominati da altri fattori oltre a ciò che si desidera misurare. Un esperimento con un grande albero sarebbe più utile. Ma questo ottiene il mio voto per aver effettivamente fatto ciò che l'OP ha chiesto.
tripleee

132

Perchè no

find <expr> | wc -l

come una semplice soluzione portatile? La tua soluzione originale sta generando un nuovo processo printf per ogni singolo file trovato, ed è molto costoso (come hai appena trovato).

Nota che questo conterà in eccesso se hai nomi di file con newline incorporati, ma se lo hai, sospetto che i tuoi problemi siano un po 'più profondi.


9
-1: si interromperà il file con una nuova riga ed è più lento del conteggio dei byte =)
Gilles Quenot

21
Non credo che ciò giustifichi un voto negativo dato che la limitazione del nome file / nuova riga è piuttosto rara e indicata sopra. Più lentamente ? Forse. Dato che stai interrogando un filesystem, sospetto che la differenza di velocità sia piccola. Nei miei 10.000 file misuro una differenza di 3 ms
Brian Agnew

8
La differenza di prestazioni tra 'find <expr> | wc -l' e 'find <expr> -printf. | wc -c 'sono estremamente piccoli. La memorizzazione nella cache (ovvero se si esegue la stessa ricerca due volte sullo stesso albero) è molto più importante. IMHO la soluzione con "wc -l" è molto più intuitiva.
pitseeker

4

Questa soluzione è certamente più lento rispetto ad alcune delle altre find -> wcsoluzioni qui, ma se si erano inclini a fare qualcosa di diverso con i nomi dei file, oltre a contarli, si poteva readdalla finduscita.

n=0
while read -r -d ''; do
    ((n++)) # count
    # maybe perform another act on file
done < <(find <expr> -print0)
echo $n

È solo una modifica di una soluzione trovata in BashGuide che gestisce correttamente i file con nomi non standard rendendo il finddelimitatore di output un byte NUL utilizzando print0e leggendo da esso utilizzando ''(byte NUL) come delimitatore di loop.


3

Questa è la mia countfilesfunzione nel mio ~/.bashrc(è ragionevolmente veloce, dovrebbe funzionare per Linux e FreeBSD finde non si lascia ingannare dai percorsi dei file contenenti caratteri di nuova riga; il finale wcconta solo NUL byte):

countfiles () 
{ 
   command find "${1:-.}" -type f -name "${2:-*}" -print0 | 
       command tr -dc '\0' | command wc -c;
return 0
}

countfiles

countfiles ~ '*.txt'
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.