Antworten:
Versuchen Sie stattdessen (erfordern find‚s - -printfUnterstützung):
find <expr> -type f -printf '.' | wc -c
Es ist zuverlässiger und schneller als das Zählen der Zeilen.
Beachten Sie, dass ich die find's verwende printf, keinen externen Befehl.
Lassen Sie uns ein wenig auf die Bank setzen:
$ ls -1
a
e
l
ll.sh
r
t
y
z
Mein Snippet-Benchmark:
$ time find -type f -printf '.' | wc -c
8
real 0m0.004s
user 0m0.000s
sys 0m0.007s
Mit vollen Zeilen:
$ time find -type f | wc -l
8
real 0m0.006s
user 0m0.003s
sys 0m0.000s
Meine Lösung ist also schneller =) (der wichtige Teil ist die realLinie)
-printf '.'
Warum nicht
find <expr> | wc -l
als einfache tragbare Lösung? Ihre ursprüngliche Lösung besteht darin , printf für jede einzelne gefundene Datei einen neuen Prozess zu erstellen, und das ist sehr teuer (wie Sie gerade gefunden haben).
Beachten Sie, dass dies zu viel zählt, wenn Sie Dateinamen mit eingebetteten Zeilenumbrüchen haben, aber wenn Sie diese haben, dann vermute ich, dass Ihre Probleme etwas tiefer gehen.
Diese Lösung ist sicherlich langsamer als einige der anderen find -> wcLösungen hier, aber wenn Sie dazu neigten, zusätzlich zu deren Zählung noch etwas anderes mit den Dateinamen zu tun, könnten Sie dies readaus der findAusgabe heraus tun .
n=0
while read -r -d ''; do
((n++)) # count
# maybe perform another act on file
done < <(find <expr> -print0)
echo $n
Es ist nur eine Modifikation einer in BashGuide gefundenen Lösung, die Dateien mit nicht standardmäßigen Namen ordnungsgemäß verarbeitet, indem das findAusgabetrennzeichen zu einem NUL-Byte gemacht print0und daraus ''(NUL-Byte) als Schleifenbegrenzer gelesen wird.
Dies ist meine countfilesFunktion in meiner ~/.bashrc(es ist ziemlich schnell, sollte für Linux & FreeBSD findfunktionieren und lässt sich nicht von Dateipfaden mit Newline-Zeichen täuschen; das Finale wczählt nur NUL-Bytes):
countfiles ()
{
command find "${1:-.}" -type f -name "${2:-*}" -print0 |
command tr -dc '\0' | command wc -c;
return 0
}
countfiles
countfiles ~ '*.txt'