"खोज" परिणामों को गिनने का सबसे अच्छा तरीका क्या है?


98

मेरा वर्तमान समाधान होगा find <expr> -exec printf '.' \; | wc -c, लेकिन जब तक 10000 से अधिक परिणाम नहीं हो जाते तब तक बहुत लंबा समय लगता है। क्या ऐसा करने का कोई तेज़ / बेहतर तरीका नहीं है?


अपने खोज परिणामों पर wc -l का प्रयोग करें
मैनुअल सेल्वा

जवाबों:


82

(की आवश्यकता होती है तब यह प्रयास करें findकी -printfसमर्थन):

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

यह लाइनों की गिनती की तुलना में अधिक विश्वसनीय और तेज होगा।

ध्यान दें कि मैं उपयोग findकी printfहै, न कि एक बाहरी कमांड।


चलो एक बिट बेंच:

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

मेरा स्निपेट बेंचमार्क:

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

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

पूरी लाइनों के साथ:

$ time find -type f | wc -l
8

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

तो मेरा हल तेज है =) (महत्वपूर्ण हिस्सा realलाइन है)


6
समतुल्य नहीं, यह अधिक विश्वसनीय है =)
गाइल्स क्वेनोट

6
यह और अधिक विश्वसनीय नहीं है अगर -printf ध्वज को खोजने के लिए अपने मंच पर समर्थित नहीं है। ;-)
रैंडी हॉवर्ड

7
ध्यान दें कि आप डॉट को उद्धृत नहीं करके कुछ और नैनोसेकंड शेव कर सकते हैं-printf '.'
जेन्स

6
@ जैन - विशेष रूप से जब आप टाइप करने में लगने वाले समय को ध्यान में रखते हैं
ब्रायन एग्न्यू

6
इस तरह के एक छोटे से बेंचमार्क के साथ, टाइमिंग शायद अन्य कारकों पर हावी हो जाती है, जिस चीज को आप मापना चाहते हैं। एक बड़े पेड़ के साथ एक प्रयोग अधिक उपयोगी होगा। लेकिन यह मेरा वोट वास्तव में ओपी के लिए पूछा गया वोट करने के लिए मिलता है।
4

132

क्यों नहीं

find <expr> | wc -l

एक सरल पोर्टेबल समाधान के रूप में? आपका मूल समाधान प्रत्येक व्यक्तिगत फ़ाइल के लिए एक नई प्रक्रिया पैदा कर रहा printf है, और यह बहुत महंगा है (जैसा कि आपने अभी पाया है)।

ध्यान दें कि यदि आप नए नाम के साथ फिल्माए गए हैं तो यह ओवरकाउंट करेगा, लेकिन अगर आपके पास ऐसा है तो मुझे संदेह है कि आपकी समस्याएं थोड़ी गहरी हैं।


9
-1: newlines के साथ फाइल पर टूट जाएगा, और यह बाइट्स गिनने की तुलना में धीमा है =)
गिलेस क्वेनोट

21
मुझे नहीं लगता है कि एक डाउनवोट दिया गया है कि फ़ाइल नाम / newline सीमा बहुत दुर्लभ है और ऊपर उल्लेख किया है। और धीमा ? शायद। यह देखते हुए कि आप एक फाइल सिस्टम को क्वेरी कर रहे हैं मुझे संदेह है कि गति अंतर छोटा है। मेरी 10,000 फाइलों के पार मैं 3ms का अंतर मापता हूं
ब्रायन एग्न्यू

8
'Find <expr> | wc -l' और 'find <expr> -printf के बीच अंतर। | wc -c 'बहुत छोटे होते हैं। कैशिंग (यानी यदि आप एक ही पेड़ पर दो बार एक ही खोज चलाते हैं) अधिक महत्वपूर्ण है। IMHO "wc -l" के साथ समाधान बहुत अधिक सहज है।
पिटसेकर

4

यह समाधान निश्चित रूप से यहां कुछ अन्य find -> wcसमाधानों की तुलना में धीमा है , लेकिन अगर आप उन्हें गिनने के अलावा फ़ाइल नामों के साथ कुछ और करने के लिए इच्छुक थे, तो आप आउटपुट readसे कर सकते थे find

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

यह बैशगाइड में पाए जाने वाले एक समाधान का एक संशोधन है जो आउटपुट डेलिमिटर को findएनयूएल बाइट का उपयोग करके गैरमानक नाम वाली फाइलों को ठीक से हैंडल करता है print0, और ''लूप सीमांकक के रूप में (एनयूएल बाइट) का उपयोग करके इसे पढ़ता है।


3

यह मेरा countfilesकार्य है ~/.bashrc(यह यथोचित रूप से तेज़ है, लिनक्स और फ्रीबीएसडी के लिए काम करना चाहिए find, और न्यूलाइन वर्णों वाले फ़ाइल पथ से मूर्ख नहीं बनता है; अंतिम wcसिर्फ एनयूएल बाइट्स की गणना करता है):

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

countfiles

countfiles ~ '*.txt'
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.