बेहतर करने के लिए “इको $ x | sed… ”और“ इको $ x | grep… ”


14

मुझे अक्सर स्क्रिप्ट में यह पता चलता है (और, मुझे स्वीकार करना होगा, इसे स्वयं लिखना होगा):

a=$(echo "$x" | sed "s/foo/bar/")

या

if echo "$x" | grep -q foo
then
    ...
fi

कुछ रेगेक्स सामान को शामिल करने के लिए "फू" पर विचार करें।

मुझे लगता है कि होना चाहिए - और सबसे अधिक संभावना है - यह वाक्यांश करने का एक बेहतर तरीका है, एक जिसमें दो कमांड और एक पाइप शामिल नहीं है लेकिन बात को कुछ और कॉम्पैक्ट अभिव्यक्ति में लपेटता है।

मैं अभी नहीं ढूँढ सकता। कोई?


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

3
वैसे, कमांड प्रतिस्थापन करने का पसंदीदा तरीका $()बैकटिक्स के बजाय है।
अगली सूचना तक रोक दिया गया।

2
विस्तार का उद्धरण देना भी एक अच्छा विचार है ताकि व्हॉट्सएप सुरक्षित रहे: a="$(echo "$x" | sed "s/foo/bar/")"और if echo "$x" | grep foo; …
क्रिस जॉन्सन

$ () बनाम `` पर अच्छी टिप्पणी। मुझे लगता है कि मेरे बैश कौशल अभी तक महान नहीं हैं।
DevSolar

जवाबों:


12

जब तक आप एक विशिष्ट शेल नहीं लेते हैं, तो "पाइप इको टू टूल" (या एक्सपेर की तरह केवल "टूल" ही ) से बेहतर कोई तरीका नहीं है ; यह सब आप वास्तव में पारंपरिक बॉर्न शेल और / या पोसिक्स शेल के साथ गिन सकते हैं । यदि आप अन्य गोले पर विचार करते हैं, तो कुछ अन्य अंतर्निहित संभावनाएं हैं।

ksh है

  • अतिरिक्त पैटर्न: ?(pattern-list), *(pattern-list), {n}(pattern-list), {n,m}(pattern-list), @(pattern-list), !(pattern-list),
  • %P printf विनिर्देशक (और एक पैटर्न में एक विस्तारित नियमित अभिव्यक्ति कन्वर्ट करने के लिए %Rपैटर्न के लिए विस्तारित नियमित अभिव्यक्ति के लिए);
  • expr == patternमें हालत [[ expr ]]परीक्षण;
  • ${param/pattern/replacement}पैरामीटर विस्तार।

बैश है

  • ksh (नहीं और ) extglobके अतिरिक्त पैटर्न को सक्षम करने का विकल्प ;{n}{n,m}
  • expr == pattern(में हालत [[ expr ]]परीक्षण);
  • ${param/pattern/replacement}पैरामीटर विस्तार;
  • (नए संस्करणों में) expr =~ extregexpस्थिति ( [[ expr ]]परीक्षणों में) जो विस्तारित नियमित अभिव्यक्तियों के खिलाफ मेल कर सकती है
    • parenthesized subexpressions और साथ BASH_REMATCHपैरामीटर, sed शैली प्रतिस्थापन किया जा सकता है।

zsh है

  • EXTENDED_GLOBविकल्प के साथ अपने स्वयं के विस्तारित पैटर्न ;
  • KSH_GLOBविकल्प के साथ ksh- जैसे विस्तारित पैटर्न ;
  • expr == pattern(में हालत [[ expr ]]परीक्षण);
  • ${pattern/pattern/replacement}पैरामीटर विस्तार;
  • expr =~ extregexpहालत (में [[ expr ]]परीक्षण) कि विस्तारित नियमित अभिव्यक्ति के खिलाफ मिलान कर सकते हैं,
    • यदि RE_MATCH_PCRE विकल्प सेट है, तो यह सादे विस्तारित नियमित अभिव्यक्तियों के बजाय PCRE का उपयोग कर सकता है।
    • parenthesized subexpressions, साथ MATCHपैरामीटर, और matchपैरामीटर (या BASH_REMATCHके साथ BASH_REMATCHविकल्प सेट), sed शैली प्रतिस्थापन किया जा सकता है;
  • zsh/pcreमॉड्यूल प्रदान करता है pcre_compile, pcre_studyऔर pcre_matchआदेश और -pcre-match परीक्षण हालत (में [[ expr ]]परीक्षण);
  • zsh/regexमॉड्यूल प्रदान करता है -regex-match परीक्षण हालत (में [[ expr ]]परीक्षण)।

वाह। जितना पूरा हो सकता है, के लिए एक इच्छा। निश्चित रूप से एक विजेता।
DevSolar

6

Sed लाइन को बदलने के लिए, कुछ ऐसा करें

${a/foo/bar} या ${a//foo/bar}

पहले रूप में, केवल पहले उदाहरण को प्रतिस्थापित किया जाता है। दूसरा रूप एक वैश्विक खोज और प्रतिस्थापित है।

आपके मामले में, यह होगा

के बजाय:

if echo $x | grep foo
then
    ...
fi

उपयोग करने पर विचार करें:

if [ $x =~ foo ]
then
    ...
fi

जहां fooएक नियमित अभिव्यक्ति है।


यह किस गोले में काम करता है?
पेल्टियर

1
if [ $x =~ foo ]यहाँ एक त्रुटि संदेश देता है। if [[ $x =~ foo ]], हालांकि, महान काम करता है। धन्यवाद!
DevSolar

1
ये सभी बैश हैं, इन्हें बैश की आवश्यकता होती है। इसके अलावा, =~bash> = 3 iirc चाहिए।
ℝaphink

1
Iirc भी, इन उदाहरणों में फू एक नियमित अभिव्यक्ति (पीसीआरई में) नहीं है, लेकिन वाइल्डकार्ड का उपयोग करता है। बैश मैनपेज, अनुभाग "पैरामीटर विस्तार" में इन बैश अच्छाई के अधिक हैं। मैं विशेष रूप से ${a##foo}और जैसी चीजों की सराहना करता हूं ${a%%bar}
ℝaphink

3
मैच ऑपरेटर =~नियमित अभिव्यक्ति का उपयोग करता है। यह सच है, उदाहरण के लिए: [[ "abcdddde" =~ ^a.*d+.g* ]](यह जी-वाइल्डकार्ड के बजाय शून्य-या-अधिक जी का है, उदाहरण के लिए)।
अगली सूचना तक रोक दिया गया।

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