मुझे रेगीक्स पात्रों के रूप में व्याख्या करने के लिए sed में रेगेक्स वर्णों से बचने की आवश्यकता क्यों है?


11

ऐसा लगता है
cat sed_data.txt | sed 's/\b[0-9]\{3\}\b/NUMBER/g'
कि मुझे नियमित अभिव्यक्ति बनाने के लिए पात्रों से बचना चाहिए । इस मामले में मुझे कई बार व्याख्या करने के लिए ब्रेसिज़ से बचना पड़ा।
क्यों? मैं उम्मीद कर रहा था कि सब कुछ एक रेगीक्स चरित्र होगा जब तक कि बच न जाए। इसके विपरीत है।


विम में खोज करने के बारे में एक पोस्ट थी जो कुछ हद तक इस सवाल को कवर करती है, "लघु संस्करण" यह कमांड के कार्यान्वयन पर निर्भर करता है "... unix.stackexchange.com/questions/90345/…
Sloan

@DravSloan: मुझे यकीन नहीं है कि यह वही है। विम आप डिफ़ॉल्ट रूप से पाठ खोजते हैं और आपको regex के लिए खोज करने के लिए भागने की जरूरत है। लेकिन इस मामले में प्रारूप s/regex//gपहले से ही एक regex की उम्मीद करता है और मुझे उम्मीद है कि यह वह पाठ होगा जिसकी आवश्यकता होगी बच निकलने के लिए
जिम

जवाबों:


14

ऐसा इसलिए है क्योंकि PREIX BREs (बेसिक रेगुलर एक्सप्रेशंस) sedका उपयोग ERE ( एक्सटेंडेड रेगुलर एक्सप्रेशंस) के विपरीत किया जाता है जिसका उपयोग आप शायद पर्ल या दोस्तों से करते हैं।

से sed(1)आदमी पेज:

REGULAR EXPRESSIONS
       POSIX.2 BREs should be supported, but they aren't completely because of
       performance problems.  The \n sequence in a regular expression  matches
       the newline character, and similarly for \a, \t, and other sequences.

उपरोक्त लिंक से प्रासंगिक उद्धरण:

बेसिक रेगुलर एक्सप्रेशंस या BRE फ्लेवर पारंपरिक UNIX grep कमांड द्वारा उपयोग किए जाने वाले स्वाद के समान है। यह आज भी उपयोग में आने वाला सबसे पुराना नियमित अभिव्यक्ति स्वाद है। एक चीज जो इस स्वाद को अलग करती है, वह यह है कि अधिकांश मेटाचैकर को मेटाचैकर को उसका स्वाद देने के लिए बैकस्लैश की आवश्यकता होती है। POSIX ERE सहित अधिकांश अन्य स्वाद, मेटाचैकर्स के अर्थ को दबाने के लिए बैकस्लैश का उपयोग करते हैं।

क्रेग सैंडर्स की टिप्पणी से उद्धृत शब्दशः :

ध्यान दें कि GNU सेड में कम से कम, आप -r या --regexp- विस्तारित कमांड लाइन विकल्प के साथ विस्तारित रेगेक्स का उपयोग करने के लिए sed बता सकते हैं। यह उपयोगी है यदि आप अत्यधिक से बचने के साथ अपने sed स्क्रिप्ट को खराब करने से बचना चाहते हैं।


1
ध्यान दें कि GNU sed में कम से कम, आप sed को रीजैक्स के उपयोग के लिए -rया --regexp-extendedकमांड लाइन विकल्प के साथ बता सकते हैं । यह उपयोगी है यदि आप अत्यधिक से बचने के साथ अपने sed स्क्रिप्ट को खराब करने से बचना चाहते हैं।
कैस

@CraigSanders इसके लिए धन्यवाद। जवाब देने के लिए जोड़ा गया।
जोसफ आर।

@ क्रेगसैंडर्स, अन्य sedकार्यान्वयन (जब वे ईआरई, ज्यादातर बीएसडी का समर्थन करते हैं) तो -Eइसके बजाय इसका उपयोग करते हैं (जो बहुत अधिक समझ में आता है क्योंकि यह उसी विकल्प के रूप में है grep। जीएनयू sedने -rमुझे क्यों चुना यह एक रहस्य है)।
स्टीफन चेज़लस

हाँ, मेरे लिए एक रहस्य भी। यह उपयोग करने के लिए और अधिक समझ में आता है -E। और फिर जोड़ -F, -G, और -P को GNU grep से मिलाएं। IMO gawk को उसी RE args से भी लाभ होगा ... या कम से कम, -P
कैस १13

12

वह ऐतिहासिक कारणों से है।

ed70 के दशक की शुरुआत में यूनिक्स में Rexxp को पहली बार पेश किया गया था। हालांकि edपर आधारित था qedजिसका कार्यान्वयन एक ही लेखकों द्वारा और अधिक जटिल regexp समझ में आया, edकेवल समझा ^, $, [...], ., *और \ऊपर के सभी से बचने के लिए।

अब, जब अधिक संचालकों की जरूरत पड़ी, तो पिछड़ी अनुकूलता को तोड़े बिना उन्हें पेश करने के लिए एक रास्ता तलाशना पड़ा। एक स्क्रिप्ट का उपयोग करने के लिए इस्तेमाल करते हैं s edआदेश के रूप में s/foo() {/foo (var) {/gकी सभी आवृत्तियों को बदलने के लिए foo() {साथ foo(var) { हैं और आप एक शुरू की (या {ऑपरेटर, कि है कि स्क्रिप्ट टूट जाएगा।

हालाँकि कोई भी स्क्रिप्ट नहीं चलेगी s/foo\(\) {/foo\(var\) {/, क्योंकि यह वही है s/foo() {/foo(var) {/और भागने का कोई कारण (नहीं था क्योंकि यह आरई ऑपरेटर नहीं था। इसलिए एक नया \(या \{ऑपरेटर शुरू करने से पिछड़ी अनुकूलता नहीं टूटती है क्योंकि पुराने सिंटैक्स का उपयोग करके किसी मौजूदा स्क्रिप्ट को तोड़ने की संभावना नहीं है।

तो, यह वही किया गया था। बाद में, \(...\)शुरू में केवल s edकमांड के लिए जोड़ा गया जैसे कि चीजों को करने के लिए s/foo\(.\)/\1bar/और बाद में grep '\(.\)\1'(लेकिन जैसी चीजें नहीं देनी चाहिए \(xx\)*)।

UnixV7 (1979, इसलिए लगभग एक दशक बाद) में, नए egrepऔर awkउपयोगिताओं में नियमित अभिव्यक्ति का एक नया रूप जोड़ा गया, जिसे विस्तारित नियमित अभिव्यक्ति कहा जाता है (क्योंकि वे नए उपकरण हैं, टूटने के लिए कोई पिछड़ी संगतता नहीं है)। अंत में, यह केन थॉम्पसन के प्राचीन qed(वैकल्पिक ऑपरेटर |, ग्रुपिंग (..)*) में उपलब्ध कार्यक्षमता के साथ प्रदान किया और जैसे कुछ ऑपरेटरों को जोड़ा ( +और ?मूल नियमित अभिव्यक्तियों की बैकएफ़ सुविधा नहीं थी)।

बाद में बीएसडी \<और \>( बीआरई \{और \}ईआरई दोनों में) जोड़े गए, और एसवाईएसवी केवल और बीआरएस में जोड़े गए ।

यह बहुत बाद तक नहीं है {और }एईआर में जोड़ा गया था, इस तरह की पिछड़ी संगतता को तोड़कर। हर किसी ने इसे नहीं जोड़ा। उदाहरण के लिए, awkसंस्करण 4.0.0 (2011) तक GNU ने समर्थन {नहीं किया जब तक कि POSIX अनुरूपता मोड में मजबूर नहीं किया गया।

जब जीएनयू grepजल्दी 90 के दशक में लिखा गया था, यह दोनों BSD और SysV से सभी उपहार (जैसे जोड़ा \<, {) और इसके बजाय BRE और ERE के लिए दो अलग-अलग regexp वाक्य रचना और इंजन होने का, दोनों में एक ही ऑपरेटरों लागू किया, केवल की BRE समकक्षों (, ?, {, +एक बैकस्लैश के साथ पहले किया जाना है (अन्य BRE कार्यान्वयन के साथ संगत होना करने के लिए)। इसीलिए आप .\+GNU में कर सकते हैं grep(हालाँकि यह POSIX या अन्य कार्यान्वयनों द्वारा समर्थित नहीं है) और आप (.)\1GNU में कर सकते हैं egrep(हालाँकि यह POSIX नहीं है या GNU सहित कई अन्य कार्यान्वयनों द्वारा समर्थित है awk)।

\xऑपरेटरों को जोड़ना केवल एक पिछड़े संगत तरीके से अधिक ऑपरेटरों को जोड़ने का तरीका नहीं है। उदाहरण के लिए, perlप्रयुक्त (?...)। यह अभी भी ईआरई के साथ पिछड़ा संगत है क्योंकि ईआरई में (?=...)मान्य नहीं है, उसी के लिए .*?vimइसी तरह के ऑपरेटरों के लिए इसे पेश करके \@=या .\{-}उदाहरण के लिए अलग तरह से किया ।

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