\\ बनाम का उपयोग कर नियमित अभिव्यक्ति


10

क्यों करता है

grep e\\.g\\. <<< "this is an e.g. wow"

तथा

grep e\.g\. <<< "this is an e.g. wow"

वहीं काम करें?

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


मैंने सोचा था कि bash लेगा \\\.और grep देगा \.लेकिन ऐसा नहीं है। अच्छा सवाल

जवाबों:


9

सबसे पहले, ध्यान दें कि एकल स्लैश बहुत अधिक मेल खाता है:

$ echo $'eegg \n e.g.' | grep e\.g\.
eegg
 e.g.

जहां तक बाश की बात है, एक बची हुई अवधि एक अवधि के समान है। बैश grep की अवधि पर गुजरता है । Grep के लिए, एक अवधि कुछ भी मेल खाती है।

अब, विचार करें:

$ echo $'eegg \n e.g.' | grep e\\.g\\.
 e.g.
$ echo $'eegg \n e.g.' | grep e\\\.g\\\.
 e.g.
$ echo $'eegg \n e.g.' | grep e\\\\.g\\\\.
$

जब बैश एक डबल-स्लैश देखता है, तो इसे एक स्लैश में कम कर देता है और उस grep पर गुजरता है, जो ऊपर दिए गए तीन परीक्षणों में से पहले, देखता है, जैसा हम चाहते हैं, एक अवधि से पहले एकल स्लैश। इस प्रकार, यह सही काम करता है।

ट्रिपल स्लैश के साथ, बैश पहले दो को सिंगल स्लैश में घटा देता है। यह तो देखता है \.। चूंकि एक बची हुई अवधि का बाश के लिए कोई विशेष अर्थ नहीं है, यह एक सादे अवधि तक कम हो जाता है। परिणाम यह है कि grep देखता है, जैसा कि हम चाहते हैं, एक अवधि से पहले स्लैश।

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

उस अंतिम को समझाने के लिए, याद रखें कि एकल-उद्धरण के अंदर, सभी वर्ण शाब्दिक हैं। इस प्रकार, निम्नलिखित तीन इनपुट लाइनें दी गई हैं, grep कमांड इनपुट में शाब्दिक स्लैश के साथ लाइन पर मेल खाता है:

$ echo 'eegg
e.g.
e\.g\.' |  grep e\\\\.g\\\\.
e\.g\.

बाश के व्यवहार का सारांश

बैश के लिए, नियम हैं

  • दो स्लैश एक स्लैश में कम हो जाते हैं।

  • एक सामान्य चरित्र के सामने एक स्लैश, जैसे एक अवधि, बस सामान्य चरित्र (अवधि) है।

इस प्रकार:

$ echo \. \\. \\\. \\\\.
. \. \. \\.

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

$ echo '\. \\. \\\. \\\\.'  # Note single-quotes
\. \\. \\\. \\\\.

प्रश्न: बैश के लिए बैकस्लैश के रूप में देखने के लिए दो बैकस्लैश लगते हैं (एक तो एस्केप सीक्वेंस है, दूसरा शाब्दिक बैकलैश है)। तो, जब 3 होते हैं तो बैश तीसरे स्ट्रैगलर को भी भागने का क्रम मानते हैं? चूंकि यह कुछ भी नहीं बच रहा है, तो क्या यह त्याग दिया गया है?
फ्रांज काफ्का

@DanielAmaya तीसरे को चरित्र के भागने के रूप में माना जाता है जो इस प्रकार है। हमारे मामले में, यह चरित्र अवधि है और, bash (grep के विपरीत) के लिए, एक बची हुई अवधि केवल एक सादे अवधि है। बैश तो ग्रीप पर सादे अवधि गुजरता है।
जॉन 1024

@DanielAmaya एक echoस्टेटमेंट के लिए अपडेट किया गया जवाब देखें जो दिखाता है कि इन मामलों में क्या करता है।
जॉन 1024

2
@DanielAmaya दोनों मामलों में, बैश एक स्लैश के पहले दो स्लैश को कम करता है। जो बचता है \.या है .। बैश के लिए, वे दोनों समान हैं: वे एक सादे अवधि के बराबर हैं। इसलिए, कुल मिलाकर, जो brep को बचाता है वह दोनों के लिए समान है: एक एकल-स्लैश जिसके बाद एक अवधि होती है।
1:10 बजे जॉन 1024

1
बस एक छोटा सा जोड़ - echoइस कार्यक्रम के कई कार्यान्वयन के कारण regexp का परीक्षण करने के लिए बहुत विश्वसनीय तरीका नहीं है। उदाहरण के लिए मेरे zsh (अंतर्निहित इको) echo \. \\. \\\. \\\\. \\\\\.देता है . \. \. \. \., लेकिन /bin/echo \. \\. \\\. \\\\. \\\\\.रिटर्न . \. \. \\. \\.। की तरह कुछ printf "%s" ...शायद बेहतर तरीका है।
जिमीज

4

आउटपुट केवल आपके स्ट्रिंग के लिए समान है, लेकिन सामान्य तौर पर वे नियमित अभिव्यक्ति अलग-अलग चीजें करते हैं। दूसरे पैटर्न e,g,(कोमा के साथ), तीसरे e\.g\.(डॉट्स), चौथे e\,g\,(कोमा), और -oकेवल मिलान वाले भागों को प्रिंट करने के लिए grep का विकल्प जोड़कर अपने उदाहरण को थोड़ा संशोधित करें ।

  • निम्नलिखित मामले में .किसी भी चार (मैच के ''आसपास नोटिस e.g., मैं बाद में आऊंगा)

    $ grep -o 'e.g.' <<< grep -o 'e.g.' <<< 'this is an e.g. e,g, e\.g\. e\,g\,'
    e.g.
    e,g,
  • अगला हम .बैकस्लैश से बचते हैं \, इसलिए केवल शाब्दिक .मिलान किया जाएगा:

    $ grep -o 'e\.g\.' <<< 'this is an e.g. e,g, e\.g\. e\,g\,'
    e.g.
  • लेकिन हम \दूसरे के साथ बच सकते हैं \, ताकि शाब्दिक \का मिलान हो सके .(अर्थात कोई भी चार):

    $ grep -o 'e\\.g\\.' <<< 'this is an e.g. e,g, e\.g\. e\,g\,'
    e\.g\.
    e\,g\,
  • लेकिन अगर हम केवल मेल करना चाहते \.हैं \,तो अभी तक \डॉट के विशेष अर्थ से बचने के लिए एक और की आवश्यकता नहीं है:

    $ grep -o 'e\\\.g\\\.' <<< 'this is an e.g. e,g, e\.g\. e\,g\,'
    e\.g\.

अब, क्योंकि आपने ''grep तर्क का उपयोग नहीं किया, इसलिए आपको शेल व्याख्या से बैकस्लैश से बचने के लिए एक और बैकस्लैश जोड़ने की आवश्यकता है, इसलिए:

grep 'e\.g\.'     => grep e\\.g\\.
grep 'e\\.g\\.'   => grep e\\\\.g\\\\.  (each backslash has to be quoted separately)
grep 'e\\\.g\\\.' => grep e\\\\\\.g\\\\\\. (3 x 2 = 6 backslashes in total)

3

जब आप ए करते हैं grep e\.g\., तो शेल बैकलैश का उपभोग कर रहा है, इस प्रकार आप एक कर रहे हैं grep e.g., जो मेल खाता है। जब आप ए करते हैं grep e\\.g\\., तो शेल फिर से एक स्लैश का उपभोग कर रहा है, और अब आप एक कर रहे हैं grep e\.\g., जो फिर से मेल खाता है। अब, शेल का बैकस्लैश जैसा दिखता है \\। इसलिए, जब आपके पास \\पहला बच निकलने का क्रम होता है, तो दूसरा एक शाब्दिक बैकलैश होता है। जब आप ए करते हैं grep e\\\.g\\\., तब भी यह समाप्त हो जाता है grep e\.\g., क्योंकि \पहले \इसे शाब्दिक बनाने के लिए एस्केप सीक्वेंस ( ) नहीं है \। ध्यान रखें \ backslash है, इस प्रकार grep e\\\\.\\\\gसमाप्त हो रहा है grep e\\.g\\., जो स्पष्ट रूप से मेल नहीं खाता है।

यह देखने के लिए कि शेल क्या देख रहा है कि आप क्या कर रहे हैं, इको का उपयोग करें (जैसे, echo grep e\\.g\\. <<< "this is an e.g. wow"बनाम echo grep e\\\\.g\\\\. <<< "this is an e.g. wow")


0

दो कमांड केवल आपके इनपुट के लिए एक ही आउटपुट का उत्पादन करते हैं लेकिन अन्यथा वे अलग हैं। क्या चल रहा है यह समझने के लिए हमें यह जानना होगा कि पहले bashऔर उसके बाद पैरामीटर की व्याख्या कैसे की जाती है grep

मारपीट में बचना

\एक विशेष चरित्र है जो \स्वयं सहित निम्नलिखित चरित्र के विशेष अर्थ को रद्द करता है। यदि निम्न वर्ण का कोई विशेष अर्थ नहीं है तो इसे बिना परिवर्तन के पारित कर दिया जाता है। आदेश और परिणाम के साथ उदाहरण:

  • echo \a: a- साधारण चरित्र बच गया चरित्र देता है
  • echo \\: \- विशेष चरित्र बच गया चरित्र देता है
  • echo \\\a: \a- संयोजन विशेष, साधारण
  • echo \\\\: \\- संयोजन विशेष, विशेष

echobashव्याख्या करने के बाद परिणामी स्ट्रिंग को प्रिंट करेगा । अधिक जानकारी: बैश डॉक्यूमेंटेशन , बैश हैकर्स विकी , पोसिक्स विनिर्देशन

.में कोई विशेष अर्थ नहीं है bash। यह शेल के लिए एक साधारण चरित्र है। नीचे आपके उदाहरणों के लिए प्रासंगिक अनुक्रम दिए गए हैं:

  • echo .: .
  • echo \.: .
  • echo \\.: \.
  • echo \\\.: \.
  • echo \\\\.: \\.

बाश में शाब्दिक तार के लिए सरल समाधान

bashआपके द्वारा शाब्दिक रूप से मापदंडों को पारित करने के लिए एकल उद्धरण से 'बचने का उपयोग किया जा सकता है । एकल उद्धरणों के बीच आपको वर्णों के विशेष अर्थ के बारे में ध्यान रखने की आवश्यकता नहीं है, क्योंकि एकल उद्धरण वहाँ केवल एक विशेष अर्थ है। आप स्ट्रिंग के पहले भाग को संलग्न करने के बाद एक एकल उद्धरण सम्मिलित कर सकते हैं। उदाहरण
echo 'part1'\''part2': part1'part2

ग्रिप में रेगेक्स

\के रूप में इसी तरह के अर्थ के साथ एक भागने चरित्र है bash.एक विशेष चरित्र है जो किसी भी चरित्र की एक घटना का प्रतिनिधित्व करता है । देखें: POSIX regex , GNU grep regex । Regex अभिव्यक्तियों के उदाहरण:

  • .- जैसे aया किसी भी पात्र से मेल खाता है.
  • \.- केवल .शाब्दिक रूप से मेल खाता है

आपके उदाहरण

हर उदाहरण की दूसरी पंक्ति पर आप एकल उद्धरण के साथ बराबर मिलेगा नीचे 'दिखाई दे रहा है, जो शाब्दिक स्ट्रिंग द्वारा पारित कर दिया है bashकरने के लिए grep। फिर grepउदाहरणों में एकमात्र संभव विशेष चरित्र से बचने के बाद .किसी भी चरित्र से मेल खाता है। तीसरी पंक्ति में एक वर्णन है कि अभिव्यक्ति क्या मेल खाती है।

  • grep e.g. <<< "this is an e.g. wow"
    grep 'e.g.' <<< "this is an e.g. wow"
    eकिसी भी चरित्र gकिसी भी चरित्र - मैच e.g.और संभवतः अन्य तार की तरहeagb
  • grep e\.g\. <<< "this is an e.g. wow"
    grep 'e.g.' <<< "this is an e.g. wow"
    eकिसी भी चरित्र gकिसी भी चरित्र - मैच e.g.और संभवतः अन्य तार की तरहexgy
  • grep e\\.g\\. <<< "this is an e.g. wow"
    grep 'e\.g\.' <<< "this is an e.g. wow"
    e.g.शाब्दिक - केवल मेल खाता हैe.g.
  • grep e\\\.g\\\. <<< "this is an e.g. wow"
    grep 'e\.g\.' <<< "this is an e.g. wow"
    e.g.शाब्दिक - केवल मेल खाता हैe.g.
  • grep e\\\\.g\\\\. <<< "this is an e.g. wow"
    grep 'e\\.g\\.' <<< "this is an e.g. wow"
    e\किसी भी चरित्र g\किसी भी चरित्र - मेल नहीं खाताe.g.
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.