मैं कैसे परीक्षण करूं कि एक चर में कई गैर-रिक्त लाइनें हैं?


10

कहते हैं कि मेरे पास दो चर हैं:

MULTILINE="I have
more than one line"
SINGLE_LINE="I only have one line
"

मैं यह पता लगाना चाहता हूं कि जब एक चर में वास्तव में पाठ की एक से अधिक रेखा होती है, तो अतिरिक्त अनुगामी न्यूलाइन वर्णों की अवहेलना होती है।

तो यह:

if [ some test on "$MULTILINE" ]; then echo 'yes'; else echo 'no'; fi

प्रिंट होगा yes, और यह:

if [ some test on "$SINGLE_LINE" ]; then echo 'yes'; else echo 'no'; fi

छपता था no

अपने विशिष्ट मामले के लिए, मुझे नहीं लगता कि मुझे प्रमुख रिक्त लाइनों के बारे में चिंता करने की ज़रूरत है, लेकिन यह जानना दुख नहीं होगा कि यह कैसे करना है।

मैं यह कैसे कर सकता हूँ?



@krowe धन्यवाद, लेकिन क्या आप वहां एक विशिष्ट उत्तर की ओर इशारा कर सकते हैं जो रिक्त लाइनों की अनुगामी है? मैंने कोई नहीं देखा। (तदनुसार शीर्षक भी संपादित किया।)
jpmc26

जवाबों:


5

सबसे सरल उपाय मुझे पता है:

if (( $(grep -c . <<<"$MULTILINE") > 1 ))

उदाहरण के लिए:

VAR="a
b"
if (( $(grep -c . <<<"$VAR") > 1 )); then
  echo VAR has more than one line
else
  echo VAR has at most one line
fi

==>

VAR has more than one line

उपरोक्त सभी रिक्त लाइनों की उपेक्षा करता है: अग्रणी, अनुगामी और आंतरिक। लेकिन ध्यान दें कि जब तक कम से कम दो गैर-रिक्त लाइनें नहीं होती हैं, तब तक आंतरिक रिक्त लाइन होना संभव नहीं है, इसलिए इसका अस्तित्व इस सवाल को बदल नहीं सकता है कि क्या खाली लाइनों को ट्रिम करने और पीछे जाने के बाद एक से अधिक रेखाएं हैं।


5
$ गूंज "$ बहु" | wc -l
2

$ गूंज "$ SINGLE_LINE" | wc -l
2

$ गूंज "$ SINGLE_LINE" | sed -re '/ ^ $ / d' | wc -l
1

$ गूंज "$ बहु" | sed -re '/ ^ $ / d' | wc -l
2

Https://stackoverflow.com/questions/16414410/delete-empty-lines-use-using देखें
कि कैसे व्हाट्सएप को खाली करने और हटाने के लिए कैसे और खाली लाइनों का उपयोग करें।

अब पंक्तियों की संख्या प्राप्त करने के लिए उद्धरण के अंदर अपना if expression ...उपयोग लिखने के $( ... )लिए, और संख्या के खिलाफ परीक्षण करें:

अगर ["$" (प्रतिध्वनि "$ MULTILINE" | sed -re '/ ^ $ / d' | wc -l) "-gt 1]; फिर
  गूंज 'एक पंक्ति से अधिक'; 
अन्य 
  इको 'सिंगल या नो लाइन'; 
फाई

0

इस कोड में थोड़ा संशोधन करना चाहिए। आप इसे इस तरह से पुन: उपयोग के लिए अपनी स्क्रिप्ट में रख सकते हैं:

#!/bin/bash
nlhit=""
for (( i=0; i<${#1}; i++ )); do
    if [[ "${1:$i:1}" == $'\n' ]]; then
        nlhit="1"
    elif [[ "$nlhit" == "1" ]]; then
        exit 1
    fi
done

exit 0

तब आप इसे इस तरह से उपयोग कर सकते हैं (यह मानते हुए कि आपने पिछली स्क्रिप्ट का नाम दिया है multiline-check.sh):

#!/bin/bash

EMPTYLINE=""
BLANKLINE="    "
ONLYLINES="


"

MULTILINE="I have
more than one line"
SINGLE_LINE="I only have one line
"
SECOND_LINE="
I begin with a newline"


echo -n "EMPTYLINE Check: "
multiline-check.sh "$EMPTYLINE"
if [ $? -eq 1 ]; then echo "Yes"; else echo "No"; fi

echo -n "BLANKLINE Check: "
multiline-check.sh "$BLANKLINE"
if [ $? -eq 1 ]; then echo "Yes"; else echo "No"; fi

echo -n "ONLYLINES Check: "
multiline-check.sh "$ONLYLINES"
if [ $? -eq 1 ]; then echo "Yes"; else echo "No"; fi

echo -n "MULTILINE Check: "
multiline-check.sh "$MULTILINE"
if [ $? -eq 1 ]; then echo "Yes"; else echo "No"; fi

echo -n "SINGLE_LINE Check: "
multiline-check.sh "$SINGLE_LINE"
if [ $? -eq 1 ]; then echo "Yes"; else echo "No"; fi

echo -n "SECOND_LINE Check: "
multiline-check.sh "$SECOND_LINE"
if [ $? -eq 1 ]; then echo "Yes"; else echo "No"; fi

मुझे पहली बार एक सिंटैक्स त्रुटि मिल रही है fi। दुर्भाग्य से, मैं 3.1 bash (msysgit संस्करण) पर अटका हुआ हूं। मुझे कुछ भी नहीं दिखता है जो मेरे लिए एक सिंटैक्स त्रुटि की तरह दिखता है, लेकिन जाहिर है मैं कुछ याद कर रहा हूं। विचार?
jpmc26

@ jpmc26 इसमें एक त्रुटि थी। मैंने इसे एक बाहरी स्क्रिप्ट के रूप में अपडेट किया है ताकि इसे उपयोग करना आसान हो।
krowe

@ jpmc26 मैंने अन्य विषम इनपुट का परीक्षण करने के लिए कुछ और चेक जोड़े हैं।
krowe

0

खाली लाइनों की उपेक्षा

यहाँ एक दृष्टिकोण का उपयोग किया गया है awk:

echo "$TEST" | tac | awk 'f==0 && /./ {f=NR} END{if(f==NR){exit 0}; exit 1 }' && echo "Found A Single Line"

यह काम किस प्रकार करता है:

  • गूंज "$ टेस्ट"

    इसमें जो भी शेल वैरिएबल होता है, उसे हम ले लेते हैं और इसे स्टैंडर्ड आउट पर भेज देते हैं।

  • tac

    यह लाइनों के क्रम को उलट देता है ताकि अंतिम पंक्ति पहले वापस आ जाए। निष्पादित करने के बाद tac, अनुगामी लाइनें अग्रणी रेखाएं बन जाती हैं।

    (नाम उस कारण tacके catलिए रिवर्स tacहै जो catकरता है लेकिन रिवर्स में करता है।)

  • awk 'f==0 && /./ {f=NR} END{if(f==NR){exit 0}; exit 1 }'

    यह चर में पहली गैर-रिक्त रेखा की पंक्ति संख्या को संग्रहीत करता है f। सभी लाइनों में पढ़ने के बाद, यह तुलना f, लाइनों की कुल संख्या के NR। यदि fइसके बराबर है NR, तो हमारे पास बस एक ही लाइन थी (प्रारंभिक रिक्त को अनदेखा करते हुए) और हम कोड के साथ बाहर निकलते हैं। 0. यदि पहली रिक्त लाइन के बाद एक या अधिक लाइनें थीं, तो यह कोड `के साथ बाहर निकलता है।

  • && echo "Found A Single Line"

    यदि awkकोड 0 के साथ बाहर निकलता है, तो echoकथन निष्पादित किया जाता है।

खाली लाइनों के अग्रणी और अनुगामी दोनों को अनदेखा करना

एक अतिरिक्त awkवैरिएबल बनाकर , हम खाली लाइनों की अग्रणी और अनुगामी दोनों को अनदेखा करने के लिए परीक्षण का विस्तार कर सकते हैं:

echo "$TEST" | awk 'first==0 && /./ {first=NR} /./ {last=NR} END{if(first==last){exit 0}; exit 1 }' && echo " Found A Single Line"

क्योंकि awkकोड का यह संस्करण प्रमुख और अनुगामी दोनों रिक्त स्थान को संभालता है, tacअब इसकी आवश्यकता नहीं है।

ले रहा है awkकोड एक समय में एक टुकड़ा:

  • first==0 && /./ {first=NR}

    यदि चर firstशून्य है (या इसे अभी तक सेट नहीं किया गया है) और लाइन में एक चरित्र, कोई भी चरित्र है, तो firstलाइन नंबर पर सेट करें। जब awkलाइनों को पढ़ा जाता है, firstतो पहले गैर-रिक्त लाइन की लाइन संख्या पर सेट किया जाएगा।

  • /./ {last=NR}

    यदि रेखा में कोई वर्ण है, तो चर lastको वर्तमान रेखा संख्या पर सेट करें । जब awkसभी पंक्तियों को पढ़ने के लिए किया जाता है, तो इस चर में अंतिम गैर-रिक्त रेखा की पंक्ति संख्या होगी।

  • END{if(first==last){exit 0}; exit 1 }

    सभी लाइनों को पढ़ने के बाद इसे निष्पादित किया गया। यदि firstबराबर है last, तो हमने शून्य या लाइन को गैर-रिक्त लाइनों के रूप में देखा है और awkकोड के साथ बाहर निकलता है 0। अन्यथा, यह कोड के साथ बाहर निकलता है 1। खोल स्क्रिप्ट के साथ हमेशा की तरह बाहर निकलने के कोड का परीक्षण कर सकते ifबयान या &&या ||

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