Risposte:
Prova questo invece (richiede find
il -printf
supporto 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 real
linea)
-printf '.'
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.
Questa soluzione è certamente più lento rispetto ad alcune delle altre find -> wc
soluzioni qui, ma se si erano inclini a fare qualcosa di diverso con i nomi dei file, oltre a contarli, si poteva read
dalla find
uscita.
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 find
delimitatore di output un byte NUL utilizzando print0
e leggendo da esso utilizzando ''
(byte NUL) come delimitatore di loop.
Questa è la mia countfiles
funzione nel mio ~/.bashrc
(è ragionevolmente veloce, dovrebbe funzionare per Linux e FreeBSD find
e non si lascia ingannare dai percorsi dei file contenenti caratteri di nuova riga; il finale wc
conta solo NUL byte):
countfiles ()
{
command find "${1:-.}" -type f -name "${2:-*}" -print0 |
command tr -dc '\0' | command wc -c;
return 0
}
countfiles
countfiles ~ '*.txt'