क्या कोई बैश कमांड है जो पैटर्न की मेल खाने वाली फ़ाइलों की संख्या को गिना जाता है?क्या कोई बैश कमांड है जो फाइलों की गणना करता है?
उदाहरण के लिए, मैं एक निर्देशिका में सभी फ़ाइलों को जो इस आकार से मिलान की गिनती प्राप्त करना चाहते हैं: log*
क्या कोई बैश कमांड है जो पैटर्न की मेल खाने वाली फ़ाइलों की संख्या को गिना जाता है?क्या कोई बैश कमांड है जो फाइलों की गणना करता है?
उदाहरण के लिए, मैं एक निर्देशिका में सभी फ़ाइलों को जो इस आकार से मिलान की गिनती प्राप्त करना चाहते हैं: log*
यह सरल एक लाइनर किसी भी खोल में काम करना चाहिए, सिर्फ पार्टी नहीं:
ls -1q log* | wc -l
ls -1q आप फ़ाइल प्रति एक लाइन दे देंगे, भले ही वे इस तरह के नई-पंक्तियों के रूप में खाली स्थान या विशेष वर्ण।
उत्पादन wc -l पर पाइप किया गया है, जो लाइनों की संख्या की गणना करता है।
इस प्रयास करें:
echo *.log | wc -w
या एक पुनरावर्ती खोज के लिए :
find . -type f -name '*.log' | wc -l
wc -w
आउटपुट में शब्दों की संख्या की गणना करता है (बैश उस पैटर्न से मेल खाने वाली फ़ाइलों की एक स्पेस से अलग सूची के रूप में *.log
का विस्तार करेगा), जबकि wc -l
लाइनों की संख्या (find
प्रिंट प्रति पंक्ति एक परिणाम) की गणना करेगा।
अद्यतन: एक गैर पुनरावर्ती खोज के लिए, ऐसा करते हैं:
find . -maxdepth 1 -type f -name '*.log' | wc -l
यह अंतरिक्ष समस्या lanzz ने उल्लेख किया धोखा देगा।
आप बैश के साथ सुरक्षित रूप से कर सकते हैं (यानी या रिक्त स्थान के साथ फ़ाइलें द्वारा bugged नहीं किया जाएगा उनके नाम में \n
):
$ shopt -s nullglob
$ logfiles=(*.log)
$ echo ${#logfiles[@]}
$ shopt -u nullglob
आप nullglob
इतना सक्षम करने के लिए है कि आप शाब्दिक नहीं मिलता है जरूरत *.log
$logfiles
array में कोई फ़ाइल नहीं मिलती है।
ls -1 log* | wc -l
सूची पैरामीटर लाइनों गिनती का उपयोग करने जा के साथ शब्द गणना आदेश के लिए प्रत्येक पंक्ति में एक फ़ाइल और फिर इसे पाइप इसका मतलब है।
"-1" विकल्प आवश्यक नहीं है। लेकिन यदि कोई फ़ाइल पैटर्न से मेल नहीं खाती है तो आप ls त्रुटि संदेश को छिपाना चाहेंगे। मैं सुझाव देता हूं "एलएस लॉग * 2>/dev/null | wc -l"। – JohnMudd
यदि आपके पास बहुत सी फाइलें हैं और आप सुरुचिपूर्ण shopt -s nullglob
और बैश सरणी समाधान का उपयोग नहीं करना चाहते हैं, तो आप फ़ाइल का नाम मुद्रित नहीं करते हैं, जब तक आप फ़ाइल का नाम प्रिंट नहीं करते हैं नई पंक्तियां)।
find -maxdepth 1 -name "log*" -not -name ".*" -printf '%i\n' | wc -l
इसमें सभी फ़ाइलें कि मैच लॉग * और उस .*
के साथ शुरू नहीं है मिलेगा - "का नाम नहीं *।" Redunant है, लेकिन यह ध्यान रखें कि "ls" के लिए डिफ़ॉल्ट नहीं है महत्वपूर्ण है डॉट-फाइलें दिखाएं, लेकिन खोज के लिए डिफ़ॉल्ट उन्हें शामिल करना है।
यह एक सही उत्तर है, और किसी भी प्रकार का फ़ाइल नाम संभाल सकता है जिसे आप फेंक सकते हैं, क्योंकि फ़ाइल नाम कमांड के बीच कभी नहीं पारित होता है।
लेकिन, shopt nullglob
उत्तर सबसे अच्छा जवाब है!
इस प्रश्न का स्वीकार्य उत्तर गलत है, लेकिन मेरे पास कम प्रतिनिधि है इसलिए इसमें कोई टिप्पणी नहीं मिल सकती है।
इस सवाल का सही जवाब चटाई द्वारा दिया जाता है:
shopt -s nullglob
logfiles=(*.log)
echo ${#logfiles[@]}
स्वीकार किए जाते हैं जवाब के साथ समस्या यह है कि WC -l मायने रखता है newline वर्णों की संख्या है, और उन्हें गिना जाता है, भले ही वे टर्मिनल के लिए प्रिंट जैसा '?' 'ls -l' के आउटपुट में। इसका मतलब है कि स्वीकार्य उत्तर विफल होता है जब फ़ाइल नाम में एक न्यूलाइन वर्ण होता है। मैं सुझाव दिया आदेश का परीक्षण किया है:
ls -l log* | wc -l
और यह ग़लती से 2 का मान है, भले ही वहाँ केवल 1 पैटर्न जिसका नाम एक नई पंक्ति वर्ण होना करने के लिए होता मिलान फ़ाइल की रिपोर्ट। उदाहरण के लिए:
touch log$'\n'def
ls log* -l | wc -l
यहाँ जवाब में से बहुत सारे हैं, लेकिन कुछ
-l
नामक एक फ़ाइल की कल्पना करें)यहाँ एक समाधान है कि उन सभी को संभालती है:
ls 2>/dev/null -Ub1 -- log* | wc -l
स्पष्टीकरण:
-U
ls
का कारण बनता है प्रविष्टियों को क्रमबद्ध नहीं करने के लिए, जिसका अर्थ यह पूरी निर्देशिका लोड करने के लिए की जरूरत नहीं है मेमोरी में लिस्टिंग-b
प्रिंट सी-शैली नोंग्राफिक वर्णों के लिए निकलती है, महत्वपूर्ण रूप से न्यूलाइन कोके रूप में मुद्रित करने का कारण बनता है।2>/dev/null
stderr को रीडायरेक्ट करता है ताकि अगर 0 लॉग फाइलें हों, तो त्रुटि संदेश को अनदेखा करें। (ध्यान दें कि shopt -s nullglob
इसके बजाय पूरी कार्य निर्देशिका को सूचीबद्ध करने के लिए ls
का कारण बन जाएगा।)wc -l
निर्देशिका सूची को उत्पन्न होने के कारण उपभोग करता है, इसलिए ls
का आउटपुट कभी भी किसी भी समय स्मृति में नहीं होता है।--
फ़ाइल नाम (मामले log*
में निकाल दिया जाता है) आदेश --
इतनी के रूप में ls
को तर्क के रूप में समझा जा नहीं का उपयोग करने से अलग होती हैखोल फाइलों की पूर्ण सूची से log*
का विस्तार होगा, अगर यह फ़ाइलों का एक बहुत कुछ है, तो उसके बाद ग्रेप के माध्यम से यह चल रहा स्मृति समाप्त हो सकती है जो बेहतर हो जाता है: के
ls -Ub1 | grep ^log | wc -l
यह पिछले एक संभालती है बहुत बड़ी निर्देशिका बहुत सारी मेमोरी का उपयोग किये बिना फाइलें (हालांकि यह सबशेल का उपयोग करती है)।
ग्रेट उत्तर और बेहद सटीक। – raratiru
इसके लिए मेरा एक लाइनर यहां है।
file_count=$(shopt -s nullglob ; set -- $directory_to_search_inside/* ; echo $#)
आपके पास अभी * विपरीत तरफ है लेकिन यह thx बहुत काम करता है – hudi
धन्यवाद, आपके प्रश्न से मेल खाने के लिए सही। :) – Daniel
मैं '-l' का उपयोग नहीं करता, क्योंकि प्रत्येक फ़ाइल पर 'stat (2)' की आवश्यकता होती है और गिनती के प्रयोजनों के लिए कुछ भी नहीं जोड़ता है। – camh