Sed में कई विस्मयादिबोधक चिह्न का उपयोग करने का क्या मतलब है?


12

POSIX sed दस्तावेज़ में कहा गया है:

एक समारोह में एक या एक से पहले हो सकता है '!' यदि पते पैटर्न पैटर्न का चयन नहीं करते हैं तो वर्ण, जिस स्थिति में फ़ंक्शन लागू किया जाएगा। शून्य या अधिक <रिक्त> वर्ण पहले स्वीकार किए जाएंगे '!' चरित्र। यह अनिर्दिष्ट है कि क्या <रिक्त> वर्ण 'अनुसरण कर सकते हैं!' चरित्र, और अनुरूपण अनुप्रयोगों का पालन नहीं होगा '!' चरित्र <रिक्त> वर्णों के साथ।

इसलिए, किसी भी POSIX sed के साथ, हम कर सकते हैं:

sed -e '/pattern/!d' file

यह लेखन के समान है:

sed -e '/pattern/!!d' file

और !!!dऔर nविस्मयादिबोधक चिह्न अभी भी ठीक हैं ( हीरलूम टूलकेस्टsed से तीन संस्करण के साथ परीक्षण किया गया )। मुझे एक विस्मयादिबोधक के बजाय कई के बीच कोई लाभ नहीं दिखता है।

कल्पना ने उस वाक्यविन्यास की अनुमति क्यों दी और यह वास्तविक विश्व अनुप्रयोग में कैसे उपयोगी है?


ऐसा लगता है कि GNU सेड इस मामले में आज्ञाकारी नहीं है, यह शिकायत करेगा कि क्या हम कई विस्मयादिबोधक का उपयोग करते हैं:

$ sed -e '/pattern/!!d' file
sed: -e expression #1, char 11: multiple `!'s

2
एफडब्ल्यूआईडब्ल्यू: ओपनबीएसडी !एक टॉगल के रूप में कार्य करता है, /pattern/!!जैसा है /pattern/, और /pattern/!!!जैसा है वैसा ही है /pattern/!। FreeBSD पर !एक एकल के रूप में कई हैं।
lcd047

2
कल्पना में बहुत सारे सामान की बात यह है कि sedलिपियों को उत्पन्न किया जा सकता है । POSIX को देखते हुए sed, स्क्रिप्ट लिखने के लिए स्क्रिप्ट के लिए यह वास्तविक रूप से सरल मामला होना चाहिए sed। और इसलिए यदि आपके पास कुछ मामले के लिए कुछ ट्रिगर !था, जो आपके कार्य के लिए योग्य नहीं के पते को चिह्नित करना चाहिए , तो आप एक ही के लिए कई बार ट्रिगर भी कर सकते हैं और अभी भी उसी परिणाम के साथ बाहर आ सकते हैं।
अक्टूबर को सुबह

@cuonglm नहीं, केवल FreeBSD है। GNU, OpenBSD और NetBSD sedनहीं हैं।
lcd047

@ lcd047: हाँ, बिल्कुल। मेरी खराब इंग्लिश के लिए माफ़ कीजिये। मेरा मतलब है कि यह आज्ञाकारी नहीं है, क्या यह है। यह जानकर अच्छा लगा। लेकिन मेरे सवाल में मुख्य बिंदु यह है कि पोसिक्स सेड के साथ वास्तविक दुनिया में वाक्यविन्यास कैसे उपयोगी हो सकता है?
कोउंगलम

1
FWIW: इसके लिए एक फिक्स OpenBSD-current में किया गया है।
lcd047

जवाबों:


5

sedएपीआई आदिम है - और यह डिजाइन द्वारा है। कम से कम, यह डिजाइन के द्वारा आदिम बना हुआ है - चाहे इसे आदिम रूप से डिजाइन किया गया हो, मैं नहीं कह सकता। ज्यादातर मामलों में एक sedस्क्रिप्ट का लेखन , जो जब चलता है, तो दूसरी sedस्क्रिप्ट को आउटपुट करेगा, वास्तव में एक साधारण मामला है। sedइस तरह से m4और / या मैक्रो प्रीप्रोसेसर द्वारा बहुत बार लागू किया जाता है make

(निम्न प्रकार एक अत्यधिक काल्पनिक उपयोग मामला है: यह एक समाधान के अनुरूप करने के लिए इंजीनियर की समस्या है। यदि यह आपके लिए एक खिंचाव की तरह महसूस करता है, तो शायद ऐसा इसलिए है क्योंकि यह है, लेकिन यह जरूरी नहीं कि इसे कोई कम वैध बना दे।)


निम्नलिखित इनपुट फ़ाइल पर विचार करें:

cat <<"" >./infile
camel
cat dog camel
dog cat
switch
upper
lower

यदि हम एक sedस्क्रिप्ट लिखना चाहते हैं, जो उपरोक्त इनपुट फ़ाइल में प्रत्येक उपयुक्त शब्द की पूंछ पर शब्द -केस जोड़ देगा, अगर यह उचित संदर्भ में एक पंक्ति में पाया जा सकता है , और हम यथासंभव कुशलता से ऐसा करना चाहते हैं ( जैसा कि हमारा लक्ष्य होना चाहिए, उदाहरण के लिए, एक संकलन ऑपरेशन के दौरान) तो हमें जितना संभव हो सके regexp s लगाने से बचना चाहिए ।//

एक चीज जो हम कर सकते हैं वह है कि अभी हमारे सिस्टम पर फ़ाइल को पूर्व-संपादित करें, और sedसंकलन के दौरान कभी भी कॉल न करें । लेकिन अगर फ़ाइल में कोई भी शब्द स्थानीय सेटिंग्स और / या संकलन-समय के विकल्पों के आधार पर शामिल होना चाहिए या नहीं होना चाहिए, तो ऐसा करने की संभावना एक वांछनीय विकल्प नहीं होगी।

एक और चीज़ जो हम कर सकते हैं वह है फ़ाइल को अब regexps के विरुद्ध संसाधित करना । हम उत्पादन कर सकते हैं - और हमारे संकलन में शामिल हैं - एक sedस्क्रिप्ट जो पंक्ति संख्या के अनुसार संपादन लागू कर सकती है - जो आमतौर पर लंबे समय में अधिक कुशल मार्ग है।

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

n=$(printf '\\\n\t')
grep -En 'camel|upper|lower' <infile |
sed "   1i${n%?}#!/usr/heirloom/bin/posix2001/sed -nf
        s/[^:]*/:&$n&!n;&!b&$n&/;s/://2;\$a${n%?}q"'
        s/ *cat/!/g;s/ *dog/!/g
        s| *\([cul][^ ]*\).*|s/.*/\1-case/p|'

... जो sedस्क्रिप्ट के रूप में आउटपुट लिखता है और जो दिखता है ...

#!/usr/heirloom/bin/posix2001/sed -nf
:1
    1!n;1!b1
    1s/.*/camel-case/p
:2
    2!n;2!b2
    2!!s/.*/camel-case/p
:5
    5!n;5!b5
    5s/.*/upper-case/p
:6
    6!n;6!b6
    6s/.*/lower-case/p
q

जब उस आउटपुट को मेरी मशीन पर एक निष्पादन योग्य पाठ फ़ाइल में सहेजा जाता है, जिसका नाम है ./bang.sedऔर जैसे है ./bang.sed ./infile, आउटपुट है:

camel-case
upper-case
lower-case

अब आप मुझसे पूछ सकते हैं ... मैं ऐसा क्यों करना चाहूंगा? मैं सिर्फ एंकर grepके मैच क्यों नहीं करूंगा ? वैसे भी ऊंट-केस का उपयोग कौन करता है? और प्रत्येक प्रश्न के लिए मैं केवल उत्तर दे सकता था, मुझे कोई पता नहीं है ... क्योंकि मैं नहीं करता। इस सवाल को पढ़ने से पहले मैंने कभी व्यक्तिगत रूप से बहु पर ध्यान नहीं दिया था ! युक्ति में आवश्यकता को पार्स करना - मुझे लगता है कि यह एक बहुत साफ पकड़ है।

बहु! बात की थी की बहुत - तुरंत हालांकि, मेरे लिए कोई मतलब sedविनिर्देश बस पार्स और बस की ओर तैयार है उत्पन्न sed स्क्रिप्ट। संभवतः आपको उस संदर्भ में बहुत अधिक समझ बनाने के \nलिए आवश्यक ईवलाइन सीमांकक मिल जाएगा [wr:bt{], और यदि आप उस विचार को ध्यान में रखते हैं, तो आप कल्पना के कुछ अन्य पहलुओं के बारे में बेहतर समझ बना सकते हैं - (जैसे :बिना पते के स्वीकार करना, और qमना करना 1 से अधिक किसी को भी स्वीकार करें)

उदाहरण में ऊपर मैं की एक निश्चित फ़ॉर्म को लिखना sedजो केवल कर सकते हैं स्क्रिप्ट कभी एक बार पढ़ा जा। यदि आप इसे मुश्किल से देखते हैं तो आप देख सकते हैं कि जैसा कि sedएडिट-फाइल को पढ़ता है यह एक कमांड-ब्लॉक से अगले तक बढ़ता है - यह कभी भी अपनी एडिट-फाइल के माध्यम से पूरी तरह से इसके एडिट-स्क्रिप्ट से दूर नहीं होता है या इसकी एडिट-स्क्रिप्ट को पूरा नहीं करता है।

मुझे लगता है कि बहु-! पते कुछ अन्य की तुलना में उस संदर्भ में अधिक उपयोगी हो सकते हैं, लेकिन, ईमानदारी से, मैं एक भी मामले के बारे में नहीं सोच सकता जिसमें मैंने इसे बहुत अच्छे उपयोग के लिए रखा हो - और मैं sedबहुत कुछ। मुझे यह भी उल्लेखनीय है कि GNU / BSD sedदोनों ही इसे निर्दिष्ट करने में विफल रहते हैं - यह संभवतः उस कल्पना का एक पहलू नहीं है जो बहुत अधिक मांग में है, और इसलिए यदि कोई कार्यान्वयन इसे नजरअंदाज करता है, तो मुझे संदेह है कि उनके कीड़े @ बॉक्स को बहुत ही पीड़ा देंगे परिणामस्वरूप।

जिसके अनुसार, विफलता निर्दिष्ट के रूप में इस संभाल करने के लिए है किसी भी लागू करने के लिए एक बग जो अनुपालन का दिखावा, और इसलिए मैं प्रासंगिक देव बक्से कहा जाता है-के लिए यहाँ है के लिए एक ईमेल शूटिंग लगता है, और मैं अगर तुम नहीं ऐसा करने के लिए करना चाहते हैं।


1
अब यह OpenBSD-current में तय हो गया है।
lcd047

1
मल्टीपल अगले सक्सेस! में हटाया जा रहा है, यहाँ क्या हो रहा है!
congonglm

@cuonglm - बहुत कम देर, मुझे लगता है। शायद मैंने सोचा था कि मैं निशान के पास था।
चाटुकार

@cuonglm - अच्छा, ठीक है, लेकिन वह क्या करता है ... चिह्नित के रूप में भी मतलब है?
चाटुकार

1
@mikeserv: जवाब ने मेरे आश्चर्य को समझाया और मुझे sed API के साथ एक और दृश्य दिया। यह मेरे लिए समझ में आता है!
कोउंगलम
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.