बैश सशर्त: कैसे "और" भाव? (यदि [-z $ VAR && -e $ VAR])


281

मुझे लगता है कि मैं स्पष्ट नहीं हूं कि मुझे कैसे करना है "और" परीक्षण। मैं यह सुनिश्चित करना चाहता था कि एक तर्क मौजूद था, जो अच्छी तरह से काम कर रहा था [ -e $VAR ], लेकिन यह पता चला है कि एक खाली स्ट्रिंग पर भी सच का मूल्यांकन कर रहा था; जो मुझे नहीं चाहिए।

मैं उन्हें 'और' एक साथ कैसे करूं? या क्या एक और अनौपचारिक परीक्षा है जो यह बताती है कि मुझे क्या चाहिए?

जवाबों:


532
if [ ! -z "$var" ] && [ -e "$var" ]; then
      # something ...
fi

9
यह समाधान कड़ाई से POSIX- संगत गोले में भी काम करता है और इसलिए इसमें भी bash; हालाँकि, "बशीज़" का पूरा फायदा उठाने के लिए, @ paxdiablo का जवाब देखें।
mklement0

2
यह देखकर बहुत ख़ुशी हुई कि यह अश्लीलता की जगह सलाह है -a
चार्ल्स डफी

1
मुझे एक और उत्कृष्ट और विस्तृत विवरण मिला - stackoverflow.com/questions/3601515/…
valentt

70

से bashमैनपेज:

[[ expression ]] - सशर्त अभिव्यक्ति की अभिव्यक्ति के मूल्यांकन के आधार पर 0 या 1 की स्थिति लौटाएं।

और, अभिव्यक्ति के लिए, विकल्पों में से एक है:

expression1 && expression2- सत्य यदि दोनों सत्य हैं expression1और expression2सत्य हैं।

तो आप andउन्हें निम्नानुसार एक साथ कर सकते हैं ( -nइसके विपरीत है -zताकि हम छुटकारा पा सकें !):

if [[ -n "$var" && -e "$var" ]] ; then
    echo "'$var' is non-empty and the file exists"
fi

हालाँकि, मुझे नहीं लगता कि इस मामले में इसकी आवश्यकता है, -e xyzzyयह सच है अगर xyzzy फ़ाइल मौजूद है और काफी आसानी से खाली तारों को संभाल सकती है। यदि आप चाहते हैं तो आपको वास्तव में -zगैर-खाली चेक की आवश्यकता नहीं है :

pax> VAR=xyzzy
pax> if [[ -e $VAR ]] ; then echo yes ; fi
pax> VAR=/tmp
pax> if [[ -e $VAR ]] ; then echo yes ; fi
yes

दूसरे शब्दों में, बस उपयोग करें:

if [[ -e "$var" ]] ; then
    echo "'$var' exists"
fi

1
हम इसे छोटा कर सकते हैं[[ -e "$var" ]] && echo "'$var' exists"
जयपाल सिंह

1
हां, अगर यह एक-लाइनर है (जैसा कि मेरा उदाहरण था)। मैं ऐसा नहीं करूंगा यदि सशर्त ब्लॉक हालांकि अधिक जटिल था।
paxdiablo

अगर केवल एक ही है - शायद इससे भी लंबा - कमांड, यह इस फॉर्म का उपयोग करने के लिए समझ में आता है क्योंकि यह छोटा है
avp

9
if [ -n "$var" -a -e "$var" ]; then
    do something ...
fi

 


10
चूंकि POSIXके व्यवहार को परिभाषित नहीं करता [परीक्षण के जटिल सेट के साथ, हम का उपयोग कर से बचना चाहिए -aया -oके साथ [। मैंने इसे यहाँ पढ़ा ।
जयपाल सिंह

2
@ jaypal-singh आप सही हैं, लेकिन विषय में bashटैग है और POSIX के बारे में उल्लेख नहीं किया गया है, इसलिए मैं इस संस्करण को पोस्ट करता हूं जो bashकुछ और आधुनिक गोले के तहत काम करता है ।
स्लाव सेमुशिन

2
यदि आप bashया अन्य आधुनिक गोले का उपयोग कर रहे हैं , तो सिफारिश करने का और भी कम कारण है -a
chepner

बैश के साथ भी, इन परीक्षणों का व्यवहार करने का तरीका सभी कोनों के मामलों में अच्छी तरह से परिभाषित नहीं है। विचार करें [ "$var1" -o "$var2" ]; यदि var1=(और var2=), फिर चाहे के लिए एक परीक्षण है कि हम क्या है -oगैर खाली, या तो है बल्कि चाहे से की var1या var2गैर खाली है। इस तरह की अस्पष्टता सही x$varमुहावरे के साथ आधुनिक (यानी, 90 के दशक के बाद) मुहावरों का एकमात्र वैध कारण है test, और उस मुहावरे को आग में मरने की जरूरत है।
चार्ल्स डफी

4

बस अपने चर बोली:

[ -e "$VAR" ]

इस का मूल्यांकन [ -e "" ]करता है, तो $VARखाली है।

आपका संस्करण काम नहीं करता क्योंकि यह मूल्यांकन करता है [ -e ]। अब इस मामले में, बस चेक करें कि क्या एकल तर्क ( -e) एक गैर-रिक्त स्ट्रिंग है।

मैनपेज से:

तर्कों की संख्या के आधार पर नियमों के एक सेट का उपयोग करके सशर्त अभिव्यक्तियों का परीक्षण और मूल्यांकन करें। ...

1 तर्क

अभिव्यक्ति सत्य है अगर और केवल अगर तर्क शून्य नहीं है।

(इसके अलावा, इस समाधान में रिक्त स्थान वाले फ़ाइलनाम के साथ काम करने का अतिरिक्त लाभ है)


1

मुझे अब एक उत्तर मिला। आपके सुझाव के लिए धन्यवाद!

for e in ./*.cutoff.txt; do
if grep -q -E 'COX1|Cu-oxidase' $e
then
    echo xyz >$e.match.txt
else
    echo
fi

if grep -q -E 'AMO' $e
then
    echo abc >$e.match.txt
else
    echo
fi; done

उस पर कोई टिप्पणी? यह दो बार grep के लिए अक्षम है, लेकिन यह काम करता है ...

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