शेल स्क्रिप्ट में केस-असंवेदनशील प्रतिस्थापन खोज [बंद]


22

मैं एक शेल स्क्रिप्ट कैसे लिख सकता हूं जो कमांड आउटपुट के केस-असंवेदनशील प्रतिस्थापन मैच करेगा?


grep -iशायद?
रमेश

मैं इसे अपनी स्क्रिप्ट के अंदर कैसे रखूंगा? मुझे खेद है कि यह एक नौसिखिया सवाल है। मैं अभी लिनक्स का अध्ययन करना शुरू कर रहा हूं क्योंकि मुझे अपनी इंटर्नशिप के लिए इसकी आवश्यकता है। धन्यवाद!
मिगुएल रोक

1
शेल स्क्रिप्टिंग के बारे में आप जो पूछ रहे हैं - "लिनक्स" एक प्रोग्रामिंग भाषा नहीं है, यह एक ऑपरेटिंग सिस्टम कर्नेल है। लिनेक्स के साथ सबसे अधिक इस्तेमाल किया जाने वाला खोल है bash, जो यूनिक्स मानकsh का एक सुपरसेट है । आप इनमें से किसी एक को देखकर शुरू कर सकते हैं: | १ | | 2 | - वास्तविक संदर्भ क्या है, इस पर पकड़ बनाने के लिए।
गोल्डीलॉक्स

1
यह प्रश्न अब काफी स्पष्ट है और सहायता केंद्र के दिशानिर्देशों से मेल खाता है। क्या यह कृपया दूसरों के लाभ के लिए खोला जा सकता है?
BobDoolittle

2
मुझे यह प्रश्न स्पष्ट नहीं है कि फ़ज़ी क्यों नहीं दिख रहा है। स्पष्ट होने के लिए मुझे क्या जोड़ना चाहिए?
मिगुएल रूक

जवाबों:


11

पहले यहाँ एक सरल उदाहरण स्क्रिप्ट है जो मामले की अनदेखी नहीं करता है:

#!/bin/bash
if [ $(echo hello) == hello ]; then
    echo it works
fi

स्ट्रिंग हेलो को दाईं ओर बदलने का प्रयास करें, और यह अब प्रतिध्वनित नहीं होना चाहिए it worksecho helloअपने चयन के आदेश के साथ बदलने का प्रयास करें । यदि आप मामले को अनदेखा करना चाहते हैं, और न ही स्ट्रिंग में एक लाइन ब्रेक शामिल है, तो आप grep का उपयोग कर सकते हैं:

#!/bin/bash
if echo Hello | grep -iqF hello; then
    echo it works
fi

यहाँ कुंजी यह है कि आप कमांड आउटपुट को पाइप कर रहे हैं grepifइस मामले ग्रेप में - बयान एक पाइप लाइन में सबसे दायीं ओर का आदेश के निकास स्थिति परीक्षण करती है। Grep सफलता के साथ बाहर निकलता है अगर और केवल अगर यह एक मैच पाता है।

-iजीआरपी का विकल्प मामले की अनदेखी करने के लिए कहता है। विकल्प नहीं फेंकना उत्पादन और पहले मैच के बाद बाहर निकलने के लिए कहते हैं। विकल्प के लिए एक नियमित अभिव्यक्ति एक स्ट्रिंग के बजाय तर्क के इलाज के लिए कहते हैं।
-q
-F

ध्यान दें कि पहला उदाहरण उपयोग करता है जो प्रत्यक्ष तुलना और विभिन्न उपयोगी ऑपरेटरों की अनुमति देता है। दूसरा रूप सिर्फ कमांड निष्पादित करता है और उनकी निकास स्थिति का परीक्षण करता है।[ expression ]


मुझे समझ नहीं आ रहा है कि गिल्स को क्यों लगा कि मेरे द्वारा योगदान किए गए कोड को बदलना आवश्यक है। उन्होंने कुछ भी नहीं तोड़ा, लेकिन यह ठीक काम किया। इस उदाहरण में आपको दोहरे उद्धरण चिह्नों की आवश्यकता नहीं है - वे महत्वपूर्ण हैं यदि आउटपुट में रिक्त स्थान शामिल हैं। और == केवल और साथ ही = काम करता है क्योंकि sh वास्तव में Linux पर बैश है। मूल बॉर्न शेल लंबे समय में इस बिंदु पर चला गया है। मुझे नहीं लगता कि सोलारिस भी इसे और अधिक जहाज करता है। इस उदाहरण में अनावश्यक होने पर मैं सहमत हूं कि दोहरे उद्धरण शायद एक सर्वोत्तम अभ्यास है, लेकिन इसलिए मेरी राय में '==' है, असाइनमेंट और तुलना को स्पष्ट रूप से अलग रखने के लिए।
BobDoolittle

रुको, तो कोई एक पोस्ट संपादित कर सकता है? मैं नहीं जानता था कि।
मिगुएल रोक

पर्याप्त प्रतिष्ठा के साथ, हाँ। मुझे उम्मीद है कि उच्च प्रतिष्ठा वाले किसी व्यक्ति को अनावश्यक एडिट करने से पहले दो बार सोचना होगा, खासकर इस फोरम में कोड करने के लिए। unix.stackexchange.com/help/privileges
BobDoolittle

@ डब ड्यूलबिटल यह कुछ खास मामलों में हो सकता है इससे फर्क पड़ता है लेकिन आपके सेटअप के साथ नहीं - यह जानना अच्छा है।

2
ध्यान दें कि व्यवहार में, यह केवल बॉर्न शेल के बारे में नहीं है। ==POSIX नहीं है सभी लिनक्स आधारित सिस्टम पर shनहीं है bash==द्वारा समर्थित नहीं है ash(जिस पर shकई बीएसडी और डेबियन डेरिवेटिव कम से कम आधारित हैं), या posh, और उद्धृत किए गए की जरूरत है zsh। कोई बात नहीं दोहरीकरण है =[परीक्षण के लिए एक आदेश है। यहां असाइनमेंट और तुलना के बीच अंतर करने की कोई आवश्यकता नहीं है। (( a == b ))बनाम में यह अलग है (( a = b))==एक स्क्रिप्ट में इसका उपयोग करना #! /bin/shगलत है। यदि आप मान लेते हैं kshया bashवाक्य रचना करते हैं, तो #!तदनुसार अपडेट करें ।
स्टीफन चेजेलस

49

यदि आप शेल विकल्प सेट करते हैं, तो आप bashरेगेक्स ऑपरेटर का उपयोग करके मूल रूप से मिलान के मामले-असंवेदनशील कर सकते हैं । उदाहरण के लिए=~nocasematch

s1="hElLo WoRlD"
s2="LO"

shopt -s nocasematch

[[ $s1 =~ $s2 ]] && echo "match" || echo "no match"
match

s1="gOoDbYe WoRlD"
[[ $s1 =~ $s2 ]] && echo "match" || echo "no match"
no match

6
जबरदस्त हंसी! अस्पष्ट खोल ज्ञान के लिए अंक।
BobDoolittle

2
यह विकल्प सरल मिलान ऑपरेटर को भी प्रभावित करता है। [[ XYZ == xyz ]] && echo "match"=>match
इसका

7

चर के मूल्य का एक केस-संवेदी स्ट्रिंग खोज के लिए needleचर के मूल्य में haystack:

case "$haystack" in
  *"$needle"*) echo "present";
  *) echo "absent";
esac

केस-असंवेदनशील स्ट्रिंग खोज के लिए, दोनों को एक ही मामले में परिवर्तित करें।

uc_needle=$(printf %s "$needle" | tr '[:lower:]' '[:upper:]' ; echo .); uc_needle=${uc_needle%.}
uc_haystack=$(printf %s "$haystack" | tr '[:lower:]' '[:upper:]' ; echo .); uc_haystack=${uc_haystack%.}
case "$uc_haystack" in
  *"$uc_needle"*) echo "present";;
  *) echo "absent";;
esac

ध्यान दें कि trGNU कोरुटिल्स मल्टीबाइट स्थानों (जैसे UTF-8) का समर्थन नहीं करता है। मल्टीबाइट स्थानों के साथ काम करने के लिए, इसके बजाय awk का उपयोग करें। यदि आप awk का उपयोग करने जा रहे हैं, तो आप इसे स्ट्रिंग तुलना कर सकते हैं, न कि केवल रूपांतरण।

if awk 'BEGIN {exit !index(toupper(ARGV[2]), toupper(ARGV[1]))}' "$needle" "$haystack"; then
  echo "present"
else
  echo "absent"
fi

trबिजीबॉक्स से समर्थन नहीं करता है वाक्य रचना; आप इसके बजाय उपयोग कर सकते हैं । बिजीबॉक्स गैर-एएससीआईआई स्थानों का समर्थन नहीं करता है।[:CLASS:]tr a-z A-Z

Bash (लेकिन श नहीं), संस्करण 4.0+ में, केस रूपांतरण के लिए अंतर्निहित सिंटैक्स और स्ट्रिंग मिलान के लिए एक सरल सिंटैक्स है।

if [[ "${haystack^^}" = *"${needle^^}"* ]]; then
  echo "present"
else
  echo "absent"
esac

मुझे लगता है कि यह कुछ साल पुराना है, लेकिन यह सब printf | trमेरे सिर के चारों ओर घूमता है। जहाँ संभव हो, अपने मंगलाचरण को कम से कम रखें ... एक चर v को देखते हुए, आप उसी चीज़ का उपयोग करके पूरा कर सकते हैं v=$(tr '[:lower:]' '[:upper:]' <<<$v)। उन लोगों के लिए जिन्होंने इसे पहले कभी नहीं देखा है, <<<अनिवार्य रूप से एक "यहां चर" है जैसे कि <<EOFयहां एक दस्तावेज़ के लिए है। मत करो printfया echoआप पूरी तरह ऐसा करने के लिए है जब तक।
विल

@Will यह केवल उन गोले में काम करता है जिनमें <<<ऑपरेटर होता है: ksh, bash, zsh, लेकिन प्लेन श नहीं। और यह printfकैसे चलता है के संदर्भ में पाइपिंग के बहुत करीब है : इसमें कॉल की एक ही संख्या है ( forkऔर execveयह माना जाता है कि printfबिल्ट-इन है, जो कि सबसे आम गोले पर मामला है); एक अंतर यह है कि <<<पाइप का उपयोग करने के बजाय एक अस्थायी फ़ाइल बनाता है। <<<टाइप करने के लिए सुविधाजनक है, लेकिन प्रदर्शन में सुधार नहीं है।
गिल्स एसओ- बुराई को रोकना '
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.