एक निर्देशिका में फ़ाइलों की संख्या की गणना करने का सबसे अच्छा तरीका क्या है?


11

यदि आउटपुट को पार्स करना lsखतरनाक है, क्योंकि यह कुछ फंकी कैरेक्टर्स (स्पेस \n, ...) पर टूट सकता है, किसी निर्देशिका में फ़ाइलों की संख्या जानने का सबसे अच्छा तरीका क्या है?

मैं सामान्य रूप findसे इस पार्सिंग से बचने के लिए भरोसा करता हूं , लेकिन इसी तरह, find mydir | wc -lसमान कारणों से टूट जाएगा।

मैं अभी सोलारिस पर काम कर रहा हूं, लेकिन मैं अलग-अलग यूनियनों में पोर्टेबल के रूप में उत्तर की तलाश कर रहा हूं और संभव के रूप में अलग-अलग गोले।


3
मुझे यकीन नहीं है कि यह एक डुप्लिकेट है, क्या मुझे कुछ याद आ रहा है?
रहमू

1
यह एक डुप्लिकेट हो सकता है, लेकिन इंगित किए गए प्रश्न का नहीं। findआपको पुनः प्राप्त होने वाली फ़ाइलों की संख्या मिल जाएगी ( -maxdepth 1यदि आप ऐसा नहीं चाहते हैं तो उपयोग करना find mydir -maxdepth 1 -type f -printf \\n | wc -lचाहिए । फ़ाइल नाम में विशेष वर्णों को संभालना चाहिए, क्योंकि वे कभी भी पहले स्थान पर मुद्रित नहीं होते हैं।
एंथॉन

जवाबों:


16

इस चाल के बारे में कैसे?

find . -maxdepth 1 -exec echo \; | wc -l

के रूप में के रूप में पोर्टेबल findऔर wc


5
यह काम नहीं करता है (यह n+1मेरे डेबियन सिस्टम पर फाइल प्रदर्शित करता है)। यह नियमित फ़ाइलों के लिए फ़िल्टर भी नहीं करता है।
क्रिस डाउन

4
मैंने सिर्फ एक सामान्य उदाहरण दिया। यह काम करता है, लेकिन यह कैसे काम करता है यह इस बात पर निर्भर करता है कि आप findअपनी विशिष्ट जरूरतों के लिए कमांड को कैसे अनुकूलित करते हैं। हां, इस एक में सभी निर्देशिकाएं शामिल हैं, .(जिसमें हो सकता है कि आप परिणाम को क्यों देखें n+1)।
रोज़ज़ेट्रिएवेज़ेज़

मुझे यह चाल पसंद है, बहुत चालाक; लेकिन मुझे आश्चर्य है कि ऐसा करने का कोई सीधा सरल तरीका नहीं है!
रहमू

3
@ क्रिसडाउन ओपी नियमित फ़ाइलों के लिए फ़िल्टरिंग निर्दिष्ट नहीं करता है, एक निर्देशिका में फ़ाइलों की संख्या के लिए पूछता है। एन + 1 मुद्दे से छुटकारा पाने के लिए, उपयोग करें find . -maxdepth 1 ! -name . -exec echo \; | wc -l; कुछ पुराने संस्करणों में findनहीं है -not
शाम

3
ध्यान दें कि -maxdepthमानक नहीं है (अब कुछ अन्य कार्यान्वयनों द्वारा समर्थित GNU एक्सटेंशन)।
स्टीफन चेजेलस

11

बैश के साथ, बाहरी उपयोगिताओं के बिना, और न ही लूप:

shopt -s dotglob
files=(*)
echo ${#files[@]}

Ksh में, shopt -s dotglobद्वारा प्रतिस्थापित करें FIGNORE=.?(.)। Zsh में, इसे बदलें setopt glob_dots, या shoptकॉल और उपयोग को हटा दें files=(*(D))। (या यदि आप डॉट फ़ाइलों को शामिल नहीं करना चाहते हैं तो बस लाइन को छोड़ दें।) यदि आप डॉट फ़ाइलों के बारे में परवाह नहीं करते हैं, तो:

set -- *
echo $#

यदि आप डॉट फाइलें शामिल करना चाहते हैं:

set -- *
if [ -e "$1" ]; then c=$#; else c=0; fi
set .[!.]*
if [ -e "$1" ]; then c=$((c+$#)); fi
set ..?*
if [ -e "$1" ]; then c=$((c+$#)); fi
echo $c

2
सक्षम नहीं 1होने पर पहला उदाहरण एक खाली निर्देशिका के लिए प्रिंट करता nullglobहै। Zsh में, a=(*(DN));echo ${#a}के साथ N( nullglob) क्वालीफायर एक खाली निर्देशिका के लिए एक त्रुटि में परिणाम नहीं करता है।
निसातमा

8
find . ! -name . -prune -print | grep -c /

80 के दशक के बाद के सिस्टम के लिए काफी पोर्टेबल होना चाहिए।

सभी निर्देशिका प्रविष्टियों को छोड़कर मायने रखता है कि .और ..वर्तमान निर्देशिका में।

उपनिर्देशिकाओं में फ़ाइलों की गणना करने के लिए:

find .//. ! -name . | grep -c //

(यह यूनिक्स V6 (1975) तक पोर्टेबल होना चाहिए, क्योंकि इसकी आवश्यकता नहीं है -prune)


इस पृष्ठ पर दुर्लभ पोर्टेबल उत्तरों में से एक, यदि एकमात्र नहीं है।
xhienne

मैंने कल इस उत्तर को बदल दिया क्योंकि मैंने पाया कि यह वर्तमान निर्देशिका ( find dirname ! -name dirname -prune -print) के अलावा अन्य निर्देशिकाओं के लिए भी अच्छा है । मैं तब से सोच रहा था कि अगर grep -c /इसके बजाय उपयोग करने के लिए कोई विशेष कारण है wc -l(जो कि आमतौर पर गिनती के लिए अधिक सामान्यतः उपयोग किया जाता है)।
एंथोनी जोगेगन

1
find dirname ! -name dirnameकाम नहीं करता है अगर वहाँ अन्य निर्देशिकाओं के नाम हैं dirname। इसका उपयोग करना बेहतर है find dirname/. ! -name .wc -lलाइनों की संख्या की गणना करता है, फ़ाइल नाम कई लाइनों से बना हो सकता है क्योंकि नई लाइन वर्ण फ़ाइल नाम में किसी भी रूप में मान्य है।
स्टीफन चेज़लस

6

प्रयत्न:

ls -b1A | wc -l

-bप्रिंट न हो सकने पात्रों होगा, -Aको छोड़कर सभी फाइलों को दिखायेगा .और ..और प्रत्येक पंक्ति में (एक पाइप पर डिफ़ॉल्ट, लेकिन अच्छी स्पष्ट होना करने के लिए) एक।

जब तक हम उच्च-स्तरीय स्क्रिप्टिंग भाषाओं को शामिल कर रहे हैं, यहाँ पायथन में एक-लाइनर है:

python -c 'import os; print len(os.listdir(os.sep))'

या पूर्ण 'खोजने' के साथ:

python -c 'import os; print len([j for i in os.walk(os.sep) for j in i[1]+i[2]])'

1

योक ऐसे निर्माण का उपयोग कर सकता है:

I=0; for i in * ; do ((I++)); done ; echo $I

लेकिन मुझे डर है, Argument list too long.अगर आप निर्देशिका में बहुत अधिक फ़ाइलें हैं तो आप त्रुटि को रोक सकते हैं । हालाँकि मैंने इसे 10 बिलियन फाइलों के साथ डायरेक्टरी में टेस्ट किया, और इसने अच्छा काम किया।


3
यह तब तक छिपी हुई फ़ाइलों के लिए काम नहीं करेगा जब तक कि उन के साथ विस्तार करने के लिए शेल को कॉन्फ़िगर नहीं किया जाता है *
लेकेन्स्टाइन

gnu find . -maxdepth 1 -type f | wc -l
निखिल मुल्ले

4
@Rush: इस कमांड को कभी भी "arg list को बहुत लंबा" नहीं बनाना चाहिए। यह केवल बाहरी आदेश के साथ होता है (इसलिए कभी नहीं for
enzotib

1

क्या आपने पर्ल पर विचार किया है, जो अपेक्षाकृत पोर्टेबल होना चाहिए?

कुछ इस तरह:

use File::Find;

$counter = 0;

sub wanted { 
  -f && ++$counter
}

find(\&wanted, @directories_to_search);
print "$counter\n";

0

इसे आज़माएँ => ls with -i (नोड संख्या के लिए) & -F ('/' के साथ डायरेक्टरी नाम का उपयोग करके) विकल्प का उपयोग करें।

ls -ilF | egrep -v '/' | wc -l

0

एक के साथ perlएक लाइनर (पठनीयता के लिए पुन: स्वरूपित):

perl -e 'opendir($dh, ".");
         while ( readdir($dh) ) {$count++};
         closedir $dh;
         print "$count\n";'

या

perl -e 'opendir($dh, ".");
         @files = readdir($dh);
         closedir $dh;
         print $#files+1,"\n";'

आप ऐसे perlफ़ंक्शन का उपयोग कर सकते हैं जो दूसरे संस्करण की तरह grepया इसके mapसाथ सरणियों को संशोधित करते हैं। perldoc -f readdirएक उदाहरण का उपयोग करके देखें grep


0

सबसे सरल संस्करण जो मैं हर समय उपयोग करता हूं और इसके साथ कभी कोई समस्या नहीं थी: ls -b1 | wc -l


यदि फ़ाइल नाम में एक \nया अन्य कायरता वर्ण हैं (तो, कुछ यूनियनों ने इसकी अनुमति दी है) आप समस्याओं में भाग सकते हैं ।
रहमू

1
मैंने अपना उत्तर पोस्ट करने से पहले यह स्पष्ट रूप से आज़माया और इसमें कोई समस्या नहीं थी। मैंने यह कोशिश करने के लिए \ n को समाहित करने के लिए एक फ़ाइल का नाम बदलने के लिए nautilus फ़ाइल प्रबंधक का उपयोग किया।
पीटर

आप सही हैं यह उस तरह काम नहीं करता है। मुझे नहीं पता कि जब मैंने यह पहला परीक्षण किया तो मैंने क्या किया। फिर से कोशिश की और मेरा जवाब अपडेट किया।
पीटर

नहीं, कमांड ठीक है, लेकिन पहले से ही एक समान समाधान है और छिपी हुई फाइलों को गिना नहीं जाता है।
xhienne

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