Solusi saya saat ini adalah find <expr> -exec printf '.' \; | wc -c
, tetapi ini memakan waktu terlalu lama ketika ada lebih dari 10.000 hasil. Apakah tidak ada cara yang lebih cepat / lebih baik untuk melakukan ini?
Jawaban:
Coba ini sebagai gantinya (membutuhkan find
's -printf
dukungan):
find <expr> -type f -printf '.' | wc -c
Ini akan lebih dapat diandalkan dan lebih cepat daripada menghitung garis.
Perhatikan bahwa saya menggunakan find
's printf
, bukan perintah eksternal.
Mari bangku sedikit:
$ ls -1
a
e
l
ll.sh
r
t
y
z
Tolok ukur cuplikan saya:
$ time find -type f -printf '.' | wc -c
8
real 0m0.004s
user 0m0.000s
sys 0m0.007s
Dengan garis penuh:
$ time find -type f | wc -l
8
real 0m0.006s
user 0m0.003s
sys 0m0.000s
Jadi solusi saya lebih cepat =) (bagian yang penting adalah real
garis)
-printf '.'
Kenapa tidak
find <expr> | wc -l
sebagai solusi portabel sederhana? Solusi asli Anda menghasilkan proses baru printf
untuk setiap file yang ditemukan, dan itu sangat mahal (seperti yang baru saja Anda temukan).
Perhatikan bahwa ini akan berlebihan jika Anda memiliki nama file dengan baris baru yang disematkan, tetapi jika Anda memilikinya maka saya curiga masalah Anda berjalan sedikit lebih dalam.
Solusi ini tentu saja lebih lambat daripada beberapa find -> wc
solusi lain di sini, tetapi jika Anda cenderung melakukan hal lain dengan nama file selain menghitungnya, Anda bisa read
dari find
output.
n=0
while read -r -d ''; do
((n++)) # count
# maybe perform another act on file
done < <(find <expr> -print0)
echo $n
Ini hanyalah modifikasi dari solusi yang ditemukan di BashGuide yang menangani file dengan nama yang tidak standar dengan benar dengan membuat find
pembatas output menjadi byte NUL menggunakan print0
, dan membacanya menggunakan ''
(NUL byte) sebagai pembatas loop.
Ini adalah countfiles
fungsi saya di saya ~/.bashrc
(ini cukup cepat, seharusnya berfungsi untuk Linux & FreeBSD find
, dan tidak tertipu oleh jalur file yang berisi karakter baris baru; yang terakhir wc
hanya menghitung byte NUL):
countfiles ()
{
command find "${1:-.}" -type f -name "${2:-*}" -print0 |
command tr -dc '\0' | command wc -c;
return 0
}
countfiles
countfiles ~ '*.txt'