जाँच करें कि क्या कोई निश्चित फ़ाइल प्रकार / एक्सटेंशन निर्देशिका में मौजूद है


84

आप यह बताने के बारे में कैसे जाएंगे कि क्या किसी निर्देशिका में विशिष्ट एक्सटेंशन की फाइलें बैश के साथ मौजूद हैं?

कुछ इस तरह

if [ -e *.flac ]; then 
echo true; 
fi 

जवाबों:


104
#!/bin/bash

count=`ls -1 *.flac 2>/dev/null | wc -l`
if [ $count != 0 ]
then 
echo true
fi 

9
हे थॉमस, कैसे के बारे में सवाल का एक बेहतर समाधान जोड़ने के बजाय सिर्फ एक downvote।
जेरेमी वीयर

8
इसके अलावा थॉमस, इसका उपयोग क्यों नहीं करने का आपका उदाहरण ls -l, मेरा जवाब उपयोग करता हैls -1
जेरेमी वियर

10
और, यह उत्तर आउटपुट को पार्स नहीं कर रहा है, यह सिर्फ लाइनों के आउटपुट की गिनती कर रहा है, और मैं लगभग निश्चित हूं, भले ही किसी फ़ाइल नाम में अजीब अक्षर हों, ls -1प्रति फ़ाइल एक लाइन प्रिंट करने जा रहा है
जेरेमी वियर

2
गिनती लाइनों है पार्स करने। और यह एक गलत संख्या लौटाएगा यदि किसी भी फाइल में \n(और हाँ, जो फ़ाइल नामों में मान्य है)।
मार्सेलम

1
प्रार्थना तो हमें बताएं, लाइन काउंट को शून्य बनाने के लिए किसी फ़ाइल के नाम में कौन सा जादुई चरित्र होना चाहिए?
योमन

27
#/bin/bash

myarray=(`find ./ -maxdepth 1 -name "*.py"`)
if [ ${#myarray[@]} -gt 0 ]; then 
    echo true 
else 
    echo false
fi

5
यह एक अच्छा है क्योंकि आप वास्तव में कर सकते हैं कर फाइलों के साथ कुछ आप उन्हें खोजने के बाद।
इफ्सिथ

मिरर्रे को एक सरणी चर बनाने के लिए कोष्ठक में मिल रहे उप-भाग को लपेटने के लिए +1। अन्यथा, यदि रिटर्न नहीं मिलता है तो परिणाम ${#myarray[@]}1
shaffooo

ls -1 *.pyखोजने के बजाय का उपयोग करके भी सरल बना सकता है
JrBenito

यदि फ़ाइलों में से किसी के नाम में जगह है, तो यह एक उदाहरण को दो के रूप में गिना जाएगा।
जॉन ग्रिफ़िथ

16

यह ls (1) का उपयोग करता है, अगर कोई flac फाइलें मौजूद नहीं हैं, ls रिपोर्ट त्रुटि और स्क्रिप्ट से बाहर निकलता है; othewise स्क्रिप्ट जारी रहती है और फ़ाइलों को संसाधित किया जा सकता है

#! /bin/sh
ls *.flac  >/dev/null || exit
## Do something with flac files here

4
अतिरिक्त चुप्पी के लिए, 2> और 1 को भी पुनर्निर्देशित करें।
जैस्पर

6
अगर संस्करण:if ls *.flac >/dev/null 2>&1; then ... fi;
जोशिया योडर


4

आपको सावधान रहना चाहिए कि आप अपने ifबयान में किस झंडे को फेंकते हैं , और यह आपके इच्छित परिणाम से कैसे संबंधित है।

यदि आप केवल नियमित फ़ाइलों और अन्य प्रकार की फ़ाइल सिस्टम प्रविष्टियों की जांच करना चाहते हैं तो आप अपना कोड कंकाल बदलना चाहते हैं:

if [ -f file ]; then
echo true;
fi

के उपयोग -fको प्रतिबंधित करता है ifनियमित रूप से फ़ाइलों को, जबकि -eअधिक प्रशस्त है और फाइल सिस्टम प्रविष्टियों के सभी प्रकार से मेल खाएगी। -dनिर्देशिका के लिए निश्चित रूप से अन्य विकल्प हैं , आदि । एक अच्छी लिस्टिंग के लिए http://tldp.org/LDP/abs/html/fto.html देखें ।

जैसा कि @msw द्वारा बताया गया है, test(अर्थात [) यदि आप कोशिश करेंगे और एक से अधिक वादों को खिलाएंगे तो वह घुट जाएगा। यदि आपके ग्लोब *.flacकी एक से अधिक फ़ाइल लौटी हैं तो यह आपके मामले में हो सकता है । उस स्थिति में अपने ifपरीक्षण को लूप में लपेटने का प्रयास करें :

for file in ./*.pdf
do
    if [ -f "${file}" ]; then
    echo 'true';
    break
    fi
done

इस तरह से आप breakचाहते हैं कि आप फ़ाइल एक्सटेंशन के पहले उदाहरण पर हैं और बाकी स्क्रिप्ट के साथ जा सकते हैं।


1
सिवाय test(उर्फ [) शिकायत करता है कि क्या पैटर्न एक से अधिक फ़ाइल में फैलता है: "बाइनरी ऑपरेटर को उम्मीद है" या "बहुत सारे तर्क"
msw

1
@msw - धन्यवाद, मैंने उस मुद्दे के बारे में सोचा भी नहीं था। मैंने अपने उत्तर को संशोधित करने का प्रयास किया है।
dtlussier 18

आपको चर का उपयोग करना चाहिए, अर्थात उपयोग करना चाहिए "$file", क्योंकि फ़ाइल नाम में कुछ बुरे वर्ण हो सकते हैं, जैसे रिक्त स्थान या तारांकन।
रोमन चेप्लाका

3
#!/bin/bash
files=$(ls /home/somedir/*.flac 2> /dev/null | wc -l)
if [ "$files" != "0" ]
then
echo "Some files exists."
else
echo "No files with that extension."
fi


3

आप यह जांचने के लिए -f का उपयोग कर सकते हैं कि क्या एक विशिष्ट प्रकार की फाइलें मौजूद हैं:

#!/bin/bash

if [ -f *.flac ] ; then
   echo true
fi 

यह काम करता है, लेकिन आप सीसा को दफन कर रहे हैं - इसका कारण यह है क्योंकि एकल ब्रेस [(अधिक सामान्य के विपरीत [[) ग्लोबिंग को रोकता नहीं है।
एड्रियन पेट्रेस्कु

2
   shopt -s nullglob
   set -- $(echo *.ext)
    if [ "${#}" -gt 0 ];then
      echo "got file"
    fi

ये गलत है। पहले, आप शायद -geइसके बजाय मतलब था -gt, क्योंकि अन्यथा आपके कोड एकल फ़ाइल का पता नहीं लगाएगा। दूसरा, यदि पैटर्न से मेल खाती हुई कोई फाइल नहीं है, तो कोई भी अनुरूप खोल स्ट्रिंग को *.extअछूता छोड़ देगा , इसलिए आपको अभी भी एक "परिणाम" मिलेगा।
रोमन चेप्लाका

$ # एक एकल फ़ाइल के लिए 1 और बिना फ़ाइलों के लिए 0 है।
फ्रैसर

1

केवल बैश:

any_with_ext () ( 
    ext="$1"
    any=false
    shopt -s nullglob
    for f in *."$ext"; do
        any=true
        break
    done
    echo $any 
)

if $( any_with_ext flac ); then
    echo "have some flac"
else 
    echo "dir is flac-free"
fi

मैं ब्रेसिज़ के बजाय कोष्ठक का उपयोग यह सुनिश्चित करने के लिए करता हूं कि एक उपधारा का उपयोग किया जाता है (अपनी वर्तमान nullglobसेटिंग को रोकना नहीं चाहते हैं )।


1

यहां कोई बाहरी कमांड (यानी नहीं ls) का उपयोग करके एक समाधान है , लेकिन इसके बजाय एक शेल फ़ंक्शन। बैश में परीक्षण किया गया:

shopt -s nullglob
function have_any() {
    [ $# -gt 0 ]
}

if have_any ./*.flac; then
    echo true
fi

फ़ंक्शन अपने तर्कों को गिनने के लिए have_anyउपयोग करता $#है, और [ $# -gt 0 ]फिर परीक्षण करता है कि क्या कम से कम एक तर्क है। कॉल में ./*.flacसिर्फ के बजाय का उपयोग करने के लिए जैसे नाम के साथ फ़ाइलों के कारण समस्याओं से बचने के *.flacलिए have_anyहै --help


1

पूरा करने के लिए, zsh के साथ:

if [[ -n *.flac(#qN) ]]; then
  echo true
fi

यह zsh मैनुअल में सशर्त अभिव्यक्तियों खंड के अंत में सूचीबद्ध है । चूंकि [[फ़ाइल नाम ग्लोबिंग को अक्षम करता है, हमें (#q)ग्लोबिंग स्ट्रिंग के अंत में उपयोग करके फ़ाइलनाम पीढ़ी को मजबूर करने की आवश्यकता होती है , फिर उत्पन्न स्ट्रिंग को खाली करने के लिए Nध्वज ( NULL_GLOBविकल्प) के मामले में कोई मैच नहीं है।


1

यहाँ एक काफी सरल उपाय है:

if [ "$(ls -A | grep -i \\.flac\$)" ]; then echo true; fi

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


मुझे यह पसंद है क्योंकि ls -AR पुनरावर्ती खोज करता है। unzipping के बाद ज़िप अभिलेखागार की सामग्री को खोजने के लिए अच्छा है।
जस्टिन just

0

मैंने यह कोशिश की:

if [ -f *.html ]; then
    echo "html files exist"
else
    echo "html files dont exist"
fi

मैंने अन्य फ़ाइलों के लिए बिना किसी समस्या के इस टुकड़े का उपयोग किया, लेकिन html फ़ाइलों के लिए मुझे एक त्रुटि मिली :

[: too many arguments

मैंने तब @ जेरेमी वियर के काउंट सॉल्यूशन की कोशिश की, जिसने मेरे लिए काम किया।

ध्यान रखें कि यदि आप एक लूप में ऐसा कर रहे हैं तो आपको गणना को रीसेट करना होगा:

count=$((0))

0

यह किसी भी वहन-योग्य शेल में काम करना चाहिए:

if [ "$(find . -maxdepth 1 -type f | grep -i '.*\.flac$')" ]; then
    echo true
fi

यह GNU के साथ भी काम करता है find, लेकिन IDK अगर यह अन्य कार्यान्वयन के साथ संगत है find:

if [ "$(find . -maxdepth 1 -type f -iname \*.flac)" ]; then
    echo true
fi
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.