2009-03-10 8 views
17

मैं वर्तमान स्तर पर फ़ोल्डरों की सूची प्राप्त करना चाहता हूं (उनके उपफोल्डर्स सहित नहीं) और फ़ोल्डर में फ़ाइलों की संख्या और केवल फ़ोल्डर में फ़ाइलों की संख्या की गणना करना (अधिमानतः फ़िल्टर करना * यदि संभव हो तो .jpg)।यूनिक्स कमांड फाइल नंबरों के साथ फ़ोल्डरों को सूचीबद्ध करने के लिए

क्या यह मानक बैश खोल में संभव है? सब कुछ है, लेकिन फाइल के बारे में ls -l प्रिंट गिनती :)

+2

। – Bernard

उत्तर

21

मैं इस एक के साथ आ गया है:

find -maxdepth 1 -type d | while read dir; do 
    count=$(find "$dir" -maxdepth 1 -iname \*.jpg | wc -l) 
    echo "$dir ; $count" 
done 

ड्रॉप दूसरा -maxdepth 1 अगर jpg फ़ाइलों के लिए निर्देशिका के भीतर खोज की उप-निर्देशिका पर विचार पुनरावर्ती होना चाहिए । ध्यान दें कि केवल फाइलों का नाम मानता है। आप एक फ़ाइल का नाम बदल सकते हैं, छुपा सकते हैं कि यह एक jpg तस्वीर है। आप बस सामग्री पर एक अनुमान करना है, बजाय file आदेश का उपयोग कर सकते हैं (अब भी रिकर्सिवली खोज):

find -mindepth 1 -maxdepth 1 -type d | while read dir; do 
    count=$(find "$dir" -type f | xargs file -b --mime-type | 
      grep 'image/jpeg' | wc -l) 
    echo "$dir ; $count" 
done 

हालांकि, कि बहुत धीमी है, क्योंकि यह फ़ाइलों का हिस्सा पढ़ने के लिए और अंत में व्याख्या है क्या उनमें शामिल हैं (यदि यह भाग्यशाली है, तो फ़ाइल की शुरुआत में यह एक जादू आईडी पाता है)। -mindepth 1 इसे . (वर्तमान निर्देशिका) को प्रिंट करने से रोकता है जो कि दूसरी निर्देशिका है।

1
#!/bin/bash 
for dir in `find . -type d | grep -v "\.$"`; do 
echo $dir 
ls $dir/*.jpg | wc -l 
done; 
8

मेरा आदेश कमांड लाइन से टाइप करने के लिए तेज़ है। :)

क्या अन्य सुझाव निम्नलिखित पर कोई वास्तविक लाभ प्रदान करते हैं?

find -name '*.jpg' | wc -l    # recursive 


find -maxdepth 1 -name '*.jpg' | wc -l # current directory only 
+0

उदाहरण: शिक्षक अपने विद्यार्थियों के जेपीजी चित्रों को सूचीबद्ध करना चाहता है। इसलिए वह आदेश/घर में रखता है और उन उप-डीआईआर में सभी जेपीजी को सूचीबद्ध करना चाहता है ताकि वे कुछ *** चीजें न हों :) मेरे पिछले यूनिक्स-शिक्षक का उदाहरण। वह जानता था कि वह क्या बोल रहा था: पी पीपीएल ने बिन फाइलों में अपने pr0n को छिपाने की कोशिश की: डी –

+0

जो केवल फाइलों की कुल संख्या प्रिंट करता है, प्रति फ़ोल्डर की संख्या नहीं। मैंने उपरोक्त टिप्पणी के बाद, इसे अभी भी किया है। – DisgruntledGoat

+0

@DisgruntledGoat, मैंने आपके प्रश्न को गलत तरीके से पढ़ा। उसके लिए माफ़ करना। मैं अब समझता हूँ। – m42

1

आप बाहरी आदेशों के बिना यह कर सकते हैं:

for d in */; do 
    set -- "$d"*.jpg 
    printf "%s: %d\n" "${d%/}" "$#" 
done 

या आप awk (nawk या /usr/xpg4/bin/awk पर सोलारिस) का उपयोग कर सकते हैं:

printf "%s\n" */*jpg | 
    awk -F\/ 'END { 
    for (d in _) 
     print d ":",_[d] 
     } 
    { _[$1]++ }' 
9

मुझे यह प्रश्न afte मिला मैं पहले से ही अपनी खुद की इसी तरह की लिपि लग रहा था। ऐसा लगता है कि यह आपकी परिस्थितियों में फिट है और बहुत लचीला है इसलिए मैंने सोचा कि मैं इसे एक उत्तर के रूप में जोड़ूंगा।

लाभ:

  • को ., 1 प्रथम स्तर उपनिर्देशिका, आदि के लिए के लिए किसी भी गहराई (0 बांटा जा सकता है)
  • प्रिंट सुंदर उत्पादन
  • कोई पाश, और केवल एक find आदेश है, इसलिए यह थोड़ा बड़े निर्देशिकाओं पर तेज है
  • अभी भी कस्टम फ़िल्टर जोड़ने के लिए (maxdepth यह गैर पुनरावर्ती बनाने के लिए नियोजित किया जा सकता, फ़ाइल नाम पैटर्न)

कच्चे कोड:

find -P . -type f | rev | cut -d/ -f2- | rev | \ 
     cut -d/ -f1-2 | cut -d/ -f2- | sort | uniq -c 

एक समारोह में लपेटा और विस्तार से बताया:

fc() { 
    # Usage: fc [depth >= 0, default 1] 
    # 1. List all files, not following symlinks. 
    #  (Add filters like -maxdepth 1 or -iname='*.jpg' here.) 
    # 2. Cut off filenames in bulk. Reverse and chop to the 
    #  first/(remove filename). Reverse back. 
    # 3. Cut everything after the specified depth, so that each line 
    #  contains only the relevant directory path 
    # 4. Cut off the preceeding '.' unless that's all there is. 
    # 5. Sort and group to unique lines with count. 

    find -P . -type f \ 
     | rev | cut -d/ -f2- | rev \ 
     | cut -d/ -f1-$((${1:-1}+1)) \ 
     | cut -d/ -f2- \ 
     | sort | uniq -c 
} 

इस तरह उत्पादन का उत्पादन:

$ fc 0 
1668 . 

$ fC# depth of 1 is default 
    6 . 
    3 .ssh 
    11 Desktop 
    44 Downloads 
1054 Music 
550 Pictures 
संख्या पहले यह sort को पहुंचाया जा सकता है के साथ बेशक

: बैश एक वास्तविक भाषा है:

$ fc | sort 
    3 .ssh 
    6 . 
    11 Desktop 
    44 Downloads 
550 Pictures 
1054 Music 
व्यक्ति जो पास मतदान करने के लिए
+0

सोलारिस पर कोई 'rev' उपलब्ध नहीं है। आप सार्वभौमिक समाधान के रूप में 'perl' का उपयोग कर सकते हैं: ' find -P। -प्रकार एफ | perl -lpe '$ _ = रिवर्स' | कट-डी/-एफ 2- | perl -lpe '$ _ = रिवर्स' | कट-डी/-एफ 1-2 | कट-डी/-एफ 2- | सॉर्ट | uniq -c' –

संबंधित मुद्दे