वहाँ `की तुलना में तेजी से कुछ भी है। | एक निर्देशिका में फ़ाइलों को गिनने के लिए wc -l`?


8

असामान्य रूप से नहीं मुझे एक निर्देशिका में फ़ाइलों की संख्या की गणना करनी है, कभी-कभी यह लाखों में चलती है।

क्या सिर्फ गणना करने और उन्हें गिनने से बेहतर तरीका है find . | wc -l? क्या किसी प्रकार की फाइलसिस्टम कॉल है जिसे आप ext3 / 4 पर बना सकते हैं जो कि कम I / O गहन है?


3
आप न केवल फाइलों की गिनती कर रहे हैं, बल्कि निर्देशिका भी। यदि आप केवल फाइलों को गिनना चाहते हैं, तो "
Find -type

एक निर्देशिका एक प्रकार की फ़ाइल है, जैसे कि डिवाइस, सिमलिंक और सॉकेट। नियमित फ़ाइलें फ़ाइलों का एक सबसेट होती हैं।
स्पाइट

1
आपके द्वारा दिया गया उदाहरण बताता है कि आप एक पुनरावर्ती गिनती चाहते हैं - यदि नहीं, तो आपको आवश्यकता है find -maxdepth 1। ध्यान दें कि आपके वर्तमान दृष्टिकोण के साथ, आप किसी भी नाम को डबल-काउंट करेंगे जिसमें एक नया वर्ण है।
स्पाइट

जवाबों:


13

मौलिक गति नहीं बल्कि कम से कम कुछ :)

find . -printf \\n | wc -l

आपको वास्तव में फ़ाइल नामों की सूची को पारित करने की आवश्यकता नहीं है, बस नए सिरे से पर्याप्त है। यह संस्करण मेरे Ubuntu 12.04.3 पर लगभग 15% तेज है जब निर्देशिकाओं को रैम में कैश किया जाता है। इसके अलावा यह संस्करण नए नामों वाली फ़ाइल नामों के साथ सही ढंग से काम करेगा।

दिलचस्प है कि यह संस्करण ऊपर वाले की तुलना में थोड़ा धीमा लगता है:

find . -printf x | wc -c

विशेष मामला - लेकिन वास्तव में तेजी से

यदि निर्देशिका अपने स्वयं के फ़ाइल सिस्टम पर है, तो आप केवल इनोड्स की गिनती कर सकते हैं:

df -i .

यदि गिने हुए की तुलना में अन्य निर्देशिकाओं में निर्देशिकाओं और फ़ाइलों की संख्या बहुत अधिक नहीं बदलती है तो आप इस ज्ञात संख्या को वर्तमान df -iपरिणाम से घटा सकते हैं । इस तरह से आप फाइलों और निर्देशिकाओं को बहुत जल्दी गिन सकेंगे।


"यह संस्करण लगभग 15% तेज है ..." मुझे आश्चर्य होता है कि क्या किसी तरह की आसान चाल है जो आप इनका उपयोग कर रहे हैं?
ब्रायन जेड

4
@ ब्रायनजेड: आप समय के साथ कमांड को दिखा कर एक कमांड दे सकते हैं। time find /usr/src/ -printf \\n | wc -l, आप के साथ रन के बीच में कैश साफ कर सकते हैंsudo sync && sudo sysctl -w vm.drop_caches=3
मैटपार्क

इसलिए मैंने बिना कैशिंग के पहले 2 विकल्पों में से 2% की लगातार वृद्धि देखी। तो हाँ यह करने का एक बहुत अच्छा तरीका है। यदि आपका वातावरण इसके लिए सेटअप है, तो इनोड्स की गिनती करना निश्चित रूप से सबसे अच्छा है। मैंने इस पर विचार नहीं किया था।
मटकाप

के -printf xरूप में ही होना चाहिए -printf '\0'? मैं इसे डॉक्स में उल्लिखित नहीं देखता।
CMCDragonkai

@CMCDragonkai: सी में फ़ंक्शन के -printfसमान printf()कार्य मुख्य अंतर के साथ कार्य करता है कि %निर्देशों का एक अलग अर्थ है। पाई गई हर फ़ाइल के लिए कार्रवाई की जाती है। इसका मतलब है कि पाया गया हर फ़ाइल के लिए -printf xवर्ण प्रिंट करेगा x(इसे आज़माएं!) और हर फ़ाइल के -printf '\0'लिए वर्ण NULL (ASCII कोड 0) प्रिंट करेगा। -printf '\0'कोई विशेष अर्थ नहीं है। दोनों wc -cइस जवाब के साथ उदाहरण में समान काम करेंगे ।
पाबौक

3

मैं वास्तव में उस उद्देश्य के लिए ffcnt लिखा है । यह fiemapioctl के साथ स्वयं निर्देशिकाओं की भौतिक ऑफसेट को पुनः प्राप्त करता है और फिर यादृच्छिक अभिगम को कम करने के लिए कई अनुक्रमिक पासों में निर्देशिका ट्रैवर्सल को शेड्यूल करता है। चाहे आप वास्तव में find | wc कई कारकों पर निर्भर करता है की तुलना में एक गति प्राप्त करें :

  • फाइलसिस्टम प्रकार: फाइलसिस्टम जैसे कि ext4 जो fiemapioctl का समर्थन करता है सबसे अधिक लाभान्वित होगा
  • रैंडम ऐक्सेस स्पीड: SSD की तुलना में HDD को ज्यादा फायदा होता है
  • निर्देशिका लेआउट: नेस्टेड निर्देशिकाओं की संख्या जितनी अधिक होगी, उतनी अधिक अनुकूलन क्षमता

(पुनः) के साथ बढ़ते relatimeया यहां तक ​​कि nodiratimeगति में सुधार हो सकता है (सभी तरीकों के लिए) जब एक्सेस अन्यथा मेटाडेटा अपडेट का कारण होगा।


वह अंतिम वाक्य एक सार्थक टिप है! मुझे लगता है कि यदि आप काम करते हैं, तो इसका एक सारांश जोड़ने पर आपके कार्यक्रम की लिंक बेहतर हो जाएगी। हम उन उत्तरों को प्राथमिकता देते हैं जो अपने आप में पूर्ण हैं, यदि लिंक किए गए संसाधन के साथ कुछ भी बुरा होता है (लेकिन लिंक को भी रखें, तो निश्चित रूप से)।
टोबे स्पाइट

2

दरअसल, मेरे सिस्टम (आर्क लिनक्स) पर यह कमांड है

   ls -A | wc -l

उपरोक्त सभी की तुलना में तेज़ है:

   $ time find . | wc -l
  1893

   real    0m0.027s
   user    0m0.004s
   sys     0m0.004s
   $ time find . -printf \\n  | wc -l
   1893

   real    0m0.009s
   user    0m0.000s
   sys     0m0.008s
   $ time find . -printf x  | wc -c
   1893

   real    0m0.009s
   user    0m0.000s
   sys     0m0.008s
   $ time ls -A | wc -l
   1892

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

मुझे लगता है कि एलएस के साथ समस्या यह है कि यह अक्सर कुछ ऐसा लौटाता है जैसे /bin/ls: Argument list too longअगर आप ग्लोबिंग का उपयोग करते हैं, लेकिन फिर यह फिर से खोजने की तरह पुनरावर्ती संचालित कर सकता है, इसलिए शायद यह विचार करने के लिए कुछ है, यदि आवश्यक नहीं है तो उपयोग न करें।
मैटपार्क

इसके बारे में टिप्पणी करने में इतनी देर (कई वर्ष) लगती है, लेकिन ls -Aवर्तमान निर्देशिका में केवल फाइलों को सूचीबद्ध करें जबकि findबिना -maxdepth 1तर्क के सभी उपनिर्देशिकाओं के माध्यम से पुनरावर्ती खोज करेंगे।
लुसियानो
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.