Apa cara terbaik untuk menghitung hasil "temukan"?
102
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?
Ini tidak lebih dapat diandalkan jika tanda -printf untuk menemukan tidak didukung di platform Anda. ;-)
Randy Howard
9
Perhatikan bahwa Anda dapat memangkas beberapa nanodetik lagi dengan tidak mengutip titik dalam-printf '.'
Jens
6
@Jens - terutama ketika Anda memperhitungkan waktu yang dibutuhkan untuk mengetik itu
Brian Agnew
7
Dengan patokan sekecil itu, pengaturan waktu mungkin didominasi oleh faktor lain selain yang ingin Anda ukur. Percobaan dengan pohon besar akan lebih bermanfaat. Tapi ini membuat saya memilih untuk benar-benar melakukan apa yang diminta OP.
tripleee
134
Kenapa tidak
find <expr> | wc -l
sebagai solusi portabel sederhana? Solusi asli Anda menghasilkan proses baruprintf 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.
-1: akan merusak file dengan baris baru, dan ini lebih lambat daripada menghitung byte =)
Gilles Quenot
24
Saya rasa tidak perlu downvote karena batasan nama file / baris baru cukup langka dan disebutkan di atas. Lebih lambat ? Mungkin. Mengingat Anda menanyakan sistem file, saya menduga perbedaan kecepatannya kecil. Di 10.000 file saya, saya mengukur perbedaan 3ms
Brian Agnew
9
Perbedaan kinerja antara 'find <expr> | wc -l' dan 'find <expr> -printf. | wc -c 'sangat kecil. Caching (yaitu jika Anda menjalankan pencarian yang sama dua kali pada pohon yang sama) jauh lebih penting. IMHO, solusi dengan "wc -l" jauh lebih intuitif.
pitseeker
5
Solusi ini tentu saja lebih lambat daripada beberapa find -> wcsolusi lain di sini, tetapi jika Anda cenderung melakukan hal lain dengan nama file selain menghitungnya, Anda bisa readdari findoutput.
n=0
whileread -r -d ''; do
((n++)) # count# maybe perform another act on filedone < <(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 findpembatas output menjadi byte NUL menggunakan print0, dan membacanya menggunakan ''(NUL byte) sebagai pembatas loop.
Ini adalah countfilesfungsi 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 wchanya menghitung byte NUL):
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
'sprintf
, bukan perintah eksternal.Mari bangku sedikit:
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)sumber
-printf '.'
Kenapa tidak
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.
sumber
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 bisaread
darifind
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 menggunakanprint0
, dan membacanya menggunakan''
(NUL byte) sebagai pembatas loop.sumber
Ini adalah
countfiles
fungsi saya di saya~/.bashrc
(ini cukup cepat, seharusnya berfungsi untuk Linux & FreeBSDfind
, dan tidak tertipu oleh jalur file yang berisi karakter baris baru; yang terakhirwc
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'
sumber