विस्तार से निर्देशिका में फ़ाइलों की गणना करें


16

परीक्षण के उद्देश्य के लिए, मैं गिनना चाहूंगा कि एक निर्देशिका के अंदर कितनी छवियां हैं, प्रत्येक छवि फ़ाइल प्रकार को फ़ाइल एक्सटेंशन (jpg = "हां" द्वारा अलग करना है। क्योंकि यह बाद में किसी अन्य स्क्रिप्ट के लिए उपयोगी होगा जो किसी कार्य को निष्पादित करेगा। प्रत्येक फ़ाइल एक्सटेंशन पर)। क्या मैं केवल JPEG फ़ाइलों के लिए निम्न जैसे कुछ का उपयोग कर सकता हूं?

jpg=""
count=`ls -1 *.jpg 2>/dev/null | wc -l`
if [ $count != 0 ]
then
echo jpg files found: $count ; jpg="yes"
fi

फ़ाइल एक्सटेंशन jpg, png, bmp, raw और अन्य को ध्यान में रखते हुए, क्या मुझे whileऐसा करने के लिए एक चक्र का उपयोग करना चाहिए ?

जवाबों:


14

मैं एक अलग दृष्टिकोण सुझाता हूँ, जिसके संभावित शब्द-विभाजन के मुद्दों से बचना चाहिए ls

#!/bin/bash

shopt -s nullglob

for ext in jpg png gif; do 
  files=( *."$ext" )
  printf 'number of %s files: %d\n' "$ext" "${#files[@]}"

  # now we can loop over all the files having the current extension
  for f in "${files[@]}"; do
    # anything else you like with these files
    :
  done 

done

आप filesकिसी भी अन्य कमांड के साथ सरणी पर लूप कर सकते हैं जिसे आप प्रत्येक विशेष एक्सटेंशन की फाइलों पर प्रदर्शन करना चाहते हैं।


अधिक स्पष्ट रूप से - या गोले के लिए जो सरणियों को स्पष्ट रूप से प्रदान नहीं करते हैं - आप शेल के स्थितीय पैरामीटर सरणी अर्थात का फिर से उपयोग कर सकते हैं

set -- *."$ext"

और उसके बाद की जगह ${#files[@]}और ${files[@]}साथ $#और"$@"


25

मेरा दृष्टिकोण होगा:

  1. निर्देशिका में सभी फ़ाइलों को सूचीबद्ध करें
  2. उनका विस्तार निकालें
  3. परिणाम को क्रमबद्ध करें
  4. प्रत्येक विस्तार की घटनाओं को गिनें

इस तरह की तरह (अंतिम awkकॉल पूरी तरह से स्वरूपण के लिए है):

ls -q -U | awk -F . '{print $NF}' | sort | uniq -c | awk '{print $2,$1}'

( विकल्प के रूप में छँटाई छोड़ने lsके -Uविकल्प के लिए यहाँ GNU मानकर । इसे कार्यक्षमता को प्रभावित किए बिना सुरक्षित रूप से हटाया जा सकता है यदि समर्थित नहीं है)।


mhh ... बाद में मुझे इसके लिए एक्शन करने के लिए मिले प्रत्येक एक्सटेंशन को फ़िल्टर करना चाहिए?
वॉचमेनस्की

यह इस बात पर निर्भर करता है कि आप आखिर में क्या करना चाहते हैं। क्या आप अधिक जानकारी दे सकते हैं?
ग्रॉक्सएक्सडा

मेरा लक्ष्य: एक स्क्रिप्ट जो प्रत्येक एक्सटेंशन फ़ाइल (केवल छवि फ़ाइल) को इनपुट उपयोगकर्ता डेटा से आकार बदलने की प्रक्रिया करती है। तो, मैं कितने jpg फ़ाइलों से शुरू कर रहा हूँ, अगले png, इत्यादि
वॉचमेनस्की

फिर स्टीलड्राइवर्स का घोल अधिक उपयुक्त हो सकता है।
19

2
मेरे पास दोनों फाइलें JPGऔर jpgफाइलें थीं , और यह पुनरावर्ती चाहता था इसलिए मेरा समाधान लिखना थाfind . -type f | awk -F . '{print tolower($NF)}' | sort | uniq -c | awk '{print $2,":",$1}'
क्रिस्टियन

11

यह पुनरावर्ती फ़ाइलों का मिलान करता है और उन एक्सटेंशनों की गणना करता है जो मेल खाते हैं:

$ find . -type f | sed -e 's/.*\.//' | sort | uniq -c | sort -n | grep -Ei '(tiff|bmp|jpeg|jpg|png|gif)$'
   6 tiff
   7 bmp
  26 jpeg
  38 gif
  51 jpg
  54 png

6
find -type f | sed -e 's/.*\.//' | sort | uniq -c

3
के साथ एक प्रारंभिक निर्देशिका मत भूलना find। इसके अलावा, यदि आप अपने समाधान का एक संक्षिप्त विवरण देते हैं (यदि वे इसे थोड़ा अलग मामले में संशोधित करना चाहते हैं) तो इन उत्तरों के भविष्य के पाठकों की मदद कर सकते हैं।
जेफ स्कालर

रिक्त स्थान वाले पथ नामों के साथ यह समाधान कितना अच्छा है? नई-पंक्तियों?
ढाग

1
findवर्तमान निर्देशिका में चूक, जो मैं इस का उपयोग करता हूं। मुझे नहीं लगता कि भगवान का नाम फिल्म्स में उनके लिए जगह है, लेकिन यह उस मामले के लिए ठीक काम करता है। यदि आपके पास नई लाइनें हैं, तो आप सभी प्राप्त करने के लायक हैं। मैंने एक स्पष्टीकरण के बारे में सोचा लेकिन फैसला किया कि यह उत्तर को बहुत लंबा कर देगा, मुझे लगता है कि सादगी क्या मायने रखती है। 1% समय में 99% मामले। यह शायद संस्करण 7 संगत है।
नीक


3

इसमें शामिल कुछ भी lsविशेष वर्ण (अंतरिक्ष और अन्य प्रतीकों) के साथ अप्रत्याशित परिणाम उत्पन्न करने की संभावना है। कोई भी बशीवाद (सरणियों की तरह) पोर्टेबल नहीं है। इसमें शामिल कुछ भी while readआमतौर पर धीमा है।

दूसरी ओर, findबहुत लचीला है (फ़िल्टर करने के लिए बहुत सारे विकल्प), इसमें [कम से कम] दो वाक्यविन्यास हैं जो विशेष वर्णों के लिए सुरक्षित नहीं हैं ... और यह बड़ी निर्देशिका पर अच्छी तरह से मापता है।

इस उदाहरण के लिए, मैंने -inameअपर और लोअर केस एक्सटेंशन नाम दोनों का मिलान किया है। मैंने -maxdepth 1आपके प्रश्न का "वर्तमान निर्देशिका में" सम्मान करने के लिए भी प्रतिबंधित किया है। लाइनों की संख्या की गिनती करने के बजाय, जहां फ़ाइलनाम में CR / LF शामिल हो सकते हैं, -print0प्रत्येक फ़ाइल नाम के अंत में एक NULL बाइट प्रिंट करेंगे ... इसलिए | tr -d -c "\000" | wc -lसटीक रूप से फ़ाइलों (NULL बाइट्स!) की गिनती कर रहा है।

extensions="jpg png gif"
for ext in $extensions; do
  c=$(find . -maxdepth 1 -iname "*.$ext" -print0 | tr -d -c "\000" | wc -c)
  if [ $c -gt 0 ]; then
    echo "Found $c  *.$ext files"

    find . -maxdepth 1 -iname "*.$ext" -print0 | xargs -0 -r -n1 DOSOMETHINGHERE
    # or #  find . -maxdepth 1 -iname "*.$ext" -exec "ls" "-l" "{}" ";"
  fi
done

पीएस के -print0 | tr -d -c "\000" | wc -cसाथ बदला जा सकता है-printf "\000" | wc -c या यहां तक ​​कि-printf '\n' | wc -l


0

बस इस सरल IMO के लिए कुछ का उपयोग कर सकते हैं

ls -l /opt/ssl/certs/*.pem | wc -l

या

count=$(ls -l /some/folder/*.jpg | wc -l)

या

ls *.{mp3,exe,mp4} 2>/dev/null | wc -l

-2

यदि आप एक्सटेंशन के बारे में सुनिश्चित हैं, तो आप इस findतरह से जा सकते हैं

find *.jpeg | wc -l

जब तक कोई बनाता है touch $'foo\nbar.jpegऔर यह एक बार के बजाय दो बार गिना जाता है। या इससे भी बदतर, कोई करता हैmkdir directory.jpeg; touch directory.jpeg/{1..100}.txt
जेफ स्कॉलर
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.