पोर्टेबल सेड के बारे में -e ... डीबी या! ख?


12

में इस संपादित स्टीफन Chazelas POSIXifies (फिर से) मेरी sedएक डालने से स्वरूपण -eहै xpression को तोड़ने और एक अन्य -eहै xpression बयान। अब, मैं उनसे सिर्फ यह पूछ सकता हूं कि टिप्पणियों में क्यों, मुझे लगता है, लेकिन यह पहले से ही उस उत्तर पर संख्या 18 में संशोधन कर रहा है और लगभग पिछले सभी पहले से ही समान मुफ्त के लिए धन्यवाद थे (यदि आप हटाए गए टिप्पणियों को देख सकते हैं तो आपको पता चल जाएगा कि आपको क्या पता होगा मेरा मतलब है) । इसके अलावा, मुझे लगता है कि मैं यह समझने के लिए पर्याप्त हूं कि इसे इस तरह से वाक्यांश क्यों कहा जाए जो आमतौर पर अधिक उपयोगी हो। तो यहाँ उम्मीद है ...

मैं आम तौर पर मेरी कुल रखना पसंद करते हैं sed -eएक के लिए xpressions अगर मैं हो सकता है, लेकिन मैं यह भी के अनुरूप के लिए एक बड़ा प्राथमिकता है कल्पना नहीं एक से अधिक है, खासकर जब अंतर मात्रा के रूप में मैं कर सकते हैं पास के रूप में <space>और एक -e। लेकिन मैं यह नहीं कर सकता अगर मुझे समझ में नहीं आता कि मुझे क्यों करना चाहिए। यहां मेरी समझ की वर्तमान स्थिति का संक्षिप्त विवरण दिया गया है:

  • ' -e 'ब्रेक portably एक के लिए में खड़े हो सकते हैं sedस्क्रिप्ट \nएक में ewline ब्रेक sedकमांड लाइन बयान ... मैं क्यों के बारे में बेशक फजी हूँ

  • किसी sed {फंक्शन में क्लोजिंग ब्रेस को यहां बताए गए ईवलाइन ब्रेक }से पहले होना चाहिए \n:

    • <right-brace>एक से पहले किया जाएगा <newline>और पहले या पालन किया जा सकता द्वारा <blank>पात्रों।
  • एक \newline तोड़ इसी तरह की ... किसी भी उपयोग निम्नलिखित की आवश्यकता है a, b, c, i, r, t, w, या :

लेकिन मुझे स्पष्ट रूप से समझ में नहीं आता है कि {फ़ंक्शन की }परिभाषा कैसे !नहीं ऑपरेटर से संबंधित है । केवल उल्लेख मैं उल्लेख राज्यों में उपेक्षा ऑपरेटर की:

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

इसका मतलब यह है कि एक !तात्कालिक {ब्रेसिज़ का उपयोग करें }? $!आज्ञाओं का क्या - क्या उन्हें इसी तरह ' -e 'टूटने से अलग किया जाना चाहिए ? यह क्या संबोधित किया गया था जब स्टीफन सबसे हाल ही में POSIXified मेरा उत्तर?

मुझे लगता है कि यह या तो !नकारात्मक संचालक है, या यह bरैंच स्टेटमेंट है जिसे वह अपने संपादन में संबोधित करता है - या संभवतः यह दोनों एक ही बार में है - लेकिन मुझे नहीं पता और इसे पसंद करना चाहिए। अगर ऐसा है हीb खेत बयान है, तो मेरा मानना है कि एक dउसके स्थान पर है और आवश्यकता को समाप्त होगा ' -e 'तोड़ने, लेकिन मेरे लिए एक तीन बार hazarding से पहले कुछ होगा POSIXified जवाब। क्या आप मदद कर सकते हैं?

मैं यह जोखिम किया सब के बाद , लेकिन किसी भी महान निश्चितता के साथ नहीं ...


के साथ b;n;:b, आप ";n;:b"ऐतिहासिक और POSIX seds (और GNU सेड उस संबंध में नहीं है) में लेबल के लिए शाखा कर रहे हैं ।
स्टीफन चेज़लस

@ स्टीफनचेलजैस - मुझे वह :हिस्सा मिलता है - जो आपने घर पर महीनों पहले चलाया था। लेकिन मुझे पूरी तरह से समझ में नहीं आता है कि दूसरी sedकमान भी इसी तरह से क्यों बनाई गई थी
mikeserv

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

1
@syntaxerror - मुझे विश्वास नहीं होता कि ऐसा ही है। यदि आप कल्पना पढ़ते हैं, तो आप पाते हैं कि s///ubstitutions एक के साथ जंजीर स्वीकार करने के लिए कल्पना कर रहे हैं ; । यह उन आदेशों के आसपास धुंधला हो जाता है, जिन्हें एक नई पंक्ति के साथ सीमांकित किया जाना चाहिए और -eउस स्थिति में कैसे खड़े हो सकते हैं - कम से कम यह मेरे लिए करता है। ive अभी तक sedउस पर ठोकर खाने के लिए नहीं है, हालांकि उनकी व्याख्या बहुत ही पारस्परिक रूप से की जाती है।
15

1
@syntaxerror - मुझे यह पसंद है, लेकिन आपको पता होना चाहिए कि आपको ;एक नई पंक्ति से पहले की आवश्यकता नहीं है - एक नई पंक्ति ठीक है। ईमानदारी से, आप पूरी तरह से और बिना पूरी तरह से कर सकते हैं -eऔर एक फाइल को लिख सकते हैं जैसे #!/bin/sedकि प्रत्येक कमांड के साथ एक नई लाइन पर - या जिनके साथ सीमांकित के बजाय ऐसे सीमांकक की आवश्यकता नहीं है ;। जो कि कर - नई-पंक्तियों की आवश्यकता होती है आमतौर पर जो कि मनमाने ढंग से इनपुट ले रहे हैं :लेबल का नाम और आदेशों की तरह उन्हें bया tया बंद करने }के कार्य अथवा के लिए curlies rEAD और wसंस्कार जो फ़ाइल नाम आर्ग ले। उन सभी को आंशिक रूप से पालन करने की आवश्यकता है \n
अभ्रक

जवाबों:


4

तो यह उच्च समय है इस सवाल का जवाब था, और, हालांकि मैंने अंत में सहज रूप से काम किया कि कैसे कुछ समय पहले हर मामले में इसे सही ढंग से करने के लिए, मैंने हाल ही में बहुत ही ठोस तरीके से पाठ को समझने में कामयाबी हासिल की । यह वास्तव में काफी स्पष्ट रूप से वहां कहा गया है - मैं बस मूर्खतापूर्वक इसे कई बार अनदेखा करता हूं, मुझे लगता है।

पाठ के प्रासंगिक अंश सभी शीर्षक के अंतर्गत पाए जाते हैं ...

  • में एडिटिंग कमांड्सsed :

    • तर्क पाठ में एक या अधिक लाइनें शामिल होंगी। \nपाठ में प्रत्येक एम्बेडेड ईवांस \बैकस्लैश से पहले होगा । पाठ के अन्य बैकस्लैश हटा दिए जाएंगे, और निम्न वर्ण का शाब्दिक उपचार किया जाएगा।

    • rऔर wआदेश क्रिया, और wकरने के लिए ध्वज sआदेश, एक वैकल्पिक ले rfile (या wfile एक या अधिक द्वारा) पैरामीटर, पत्र या झंडा क्रिया आदेश से अलग कर दिया <blank>s; क्रियान्वयन विस्तार के रूप में शून्य पृथक्करण की अनुमति दे सकता है।

    • कमान के अलावा अन्य verbs {, a, b, c, i, r, t, w, :, और #एक के बाद किया जा सकता है ;अर्धविराम, वैकल्पिक <blank>s, और एक अन्य आदेश क्रिया। हालाँकि, जब sकमांड क्रिया का उपयोग wध्वज के साथ किया जाता है , तो इस तरीके से किसी अन्य आदेश के साथ पालन करने से अपरिभाषित परिणाम उत्पन्न होते हैं।

... में ...

  • विकल्प: कई -eऔर -fविकल्प निर्दिष्ट किए जा सकते हैं। सभी आदेशों को उनके मूल की परवाह किए बिना निर्दिष्ट स्क्रिप्ट में जोड़ा जाएगा।

    • -e स्क्रिप्ट - द्वारा निर्दिष्ट संपादन आदेशों जोड़े स्क्रिप्ट के अंत करने के लिए विकल्प तर्क स्क्रिप्ट संपादन आदेशों की। स्क्रिप्ट विकल्प-तर्क के रूप में एक ही गुण होगा स्क्रिप्ट संकार्य, में वर्णित ऑपरेंड अनुभाग।

    • -f script_file - स्क्रिप्ट के अंत में file script_file में संपादन कमांड जोड़ें ।

और अंतिम में ...

  • ऑपरेंड:

    • स्क्रिप्ट - एक स्ट्रिंग जो एडिटिंग कमांड की स्क्रिप्ट के रूप में उपयोग की जाती है । एप्लिकेशन एक स्क्रिप्ट प्रस्तुत नहीं करेगा जो पाठ फ़ाइल के प्रतिबंधों का उल्लंघन करता है, सिवाय इसके कि अंतिम चरित्र को एक \newline की आवश्यकता नहीं है ।

इसलिए, जब आप इसे पूरी तरह से लेते हैं, तो यह समझ में आता है कि कोई भी आदेश जो वैकल्पिक रूप सेs d sub d repl d flag पूर्वनिर्धारित परिसीमन के बिना एक मनमाना पैरामीटर द्वारा अनुसरण किया जाता है ( उदाहरण के लिए विरोध के रूप में ) एक बिना किसी \nअवांछित रेखा के परिसीमन करना चाहिए ।

ऐसा नहीं है कि विवादास्पद है ; है एक पूर्वनिर्धारित सीमांकक लेकिन इस मामले में का उपयोग कर ;से किसी के लिए [aic]अलग, कि के लिए इस्तेमाल किया पार्सर से है, - आदेशों की जरूरत है कि एक अलग पार्सर उन तीन आदेशों के लिए विशेष रूप कार्यान्वयन में शामिल किया जाना [:brw]उदाहरण के लिए,। या फिर कार्यान्वयन के लिए यह आवश्यक होगा कि पाठ पैरामीटर के भीतर ; भी बैकस्लैश बच जाए और यह केवल वहां से अधिक जटिल हो जाए।

अगर मैं ऐसा लिख रहा था, sedजिसे मैं दोनों आज्ञाकारी और कुशल होना चाहता था, तो मैं इस तरह का एक अलग पार्सर नहीं लिखूंगा, मैं उम्मीद करता हूं - सिवाय इसके कि शायद [aic]एक वाक्यविन्यास त्रुटि को जीन किया जाए यदि एक \nइवलाइन द्वारा तुरंत नहीं । लेकिन यह एक साधारण टोकन समस्या है - अंत में सीमांकक मामला आम तौर पर अधिक समस्याग्रस्त है। मैं बस इतना लिखूंगा:

sed -e w\ file\\ -e one -e '...;and more commands'

...तथा...

sed -e a\\ -e appended\\ -e text -e '...;and more commands'

... बहुत समान व्यवहार करेंगे, जिसमें पहले एक फाइल बनाई जाएगी और नाम लिखा जाएगा:

file
one

... और दूसरा आउटपुट पर वर्तमान लाइन के लिए टेक्स्ट के एक ब्लॉक को जोड़ देगा ...

appended
text

... क्योंकि दोनों पैरामीटर के लिए एक ही पार्सिंग कोड साझा करेंगे।

और के बारे में { ... }और $!मुद्दा - ठीक है, मुझे रास्ता बंद हो गया। एक पते से पहले एक एकल आदेश एक फ़ंक्शन नहीं है, बल्कि यह केवल एक संबोधित आदेश है। फ़ंक्शन और परिभाषा सहित लगभग सभी कमांड - टिप्पणी और लेबल परिभाषा के अपवाद के साथ स्वीकार करने या संबोधित करने के लिए निर्दिष्ट हैं । और एक पता या तो एक लाइन नंबर या एक नियमित एक्सप्रेस हो सकता है और इसके साथ नकारात्मक हो सकता है । इसलिए सभी ...{ }/one//one/,/two/#:!

$!d
/address/s/ub/stitution/
5!y/d/c/

... ;मानक के अनुसार एक और अधिक आदेशों का पालन ​​किया जा सकता है , लेकिन यदि किसी एकल पते के लिए अधिक आदेशों की आवश्यकता होती है, और प्रत्येक कमांड के निष्पादन के बाद उस पते का पुनर्मूल्यांकन नहीं किया जाना चाहिए, तो एक {फ़ंक्शन }का उपयोग किया जाना चाहिए:

/address/{ s//replace addressed pattern/
           s/do other conditional/substitutions/
           s/in the same context/without/
           s/reevaluating/address/
}

... जहां {एक समापन के द्वारा एक ही लाइन पर पालन नहीं किया जा सकता है }और यह कि }एक लाइन की शुरुआत को छोड़कर कोई समापन नहीं हो सकता है। लेकिन अगर एक सम्‍मिलित कमांड को अन्यथा \newline द्वारा अनुसरण नहीं किया जाना चाहिए , तो इसे फ़ंक्शन के भीतर भी नहीं होना चाहिए । तो उपरोक्त सभी s///ubstitutions - और यहां तक ​​कि समापन }ब्रेस, को ;अर्धविराम और आगे के आदेशों के साथ आंशिक रूप से पालन ​​किया जा सकता है ।

मैं \newline delimiters के बारे में बात कर रहा हूँ, लेकिन सवाल xpression -eबयानों के बारे में है , मुझे पता है। लेकिन दोनों वास्तव में एक और एक ही हैं, और महत्वपूर्ण संबंध यह है कि एक स्क्रिप्ट या तो एक शाब्दिक कमांड-लाइन तर्क हो सकती है या दोनों में से एक फ़ाइल हो सकती है -[ef], और दोनों को पाठ फ़ाइलों के रूप में व्याख्या की जाती है (जो एक में समाप्त होने के लिए निर्दिष्ट हैं। \newline) लेकिन न तो वास्तव में एक ewline में समाप्त होने की जरूरत है \n। इसके द्वारा मैं यथोचित रूप से (मुझे आशा है) अनुमान लगाता \0NULहै कि एक सीमांकित तर्क का अर्थ एक अंतिम \nपंक्ति है, और जैसा कि सभी आह्वान तर्क कम से कम प्राप्त करते हैं)\0NUL वैसे भी एक सीमांकक है, तो या तो ठीक काम करना चाहिए।

वास्तव में, व्यवहार में, हर मामले में, लेकिन एक मानक जहां एक \बैकस्लैश बची हुई नईलाइन की आवश्यकता होती है, मुझे आवश्यक रूप से मिल जाना चाहिए ...

sed -e ... -e '...\' -e '...'

... साथ ही काम करना है। और हर मामले में - फिर से, व्यवहार में - जहां एक गैर- \nबची हुई ईवलाइन की आवश्यकता होनी चाहिए ...

sed -e '...' -e '...'

... मेरे लिए भी काम किया है। एक अपवाद जिसका मैं ऊपर उल्लेख कर रहा हूं ...

sed -e 's/.../...\' -e '.../'

... जो मेरे किसी भी परीक्षण में किसी भी कार्यान्वयन के लिए काम नहीं करता है। मुझे पूरा यकीन है कि पाठ फ़ाइल की आवश्यकता और तथ्य यह है कि एक सीमांकक के साथ s/// आता है और इसलिए कोई कारण नहीं है कि एक बयान में \0NULसीमांकित तर्कों का विस्तार होना चाहिए ।

इसलिए, निष्कर्ष में, कई प्रकार के sedआदेशों को लिखने के लिए पोर्टेबल तरीके का एक संक्षिप्त तरीका है :

किसी के लिए [aic]:

...commands;[aic]\
text embedded newline\
delimiting newline
...more;commands...

... या ...

sed -e '...commands;[aic]\' -e 'text embedded newline\' -e 'delimiting newline' -e '.;.;.'

में से किसी के लिए [:rwtb]जहां पैरामीटर है वैकल्पिक (सभी लेकिन के लिए :) लेकिन परिसीमन \newline है नहीं । नोट मैं एक कारण बहु पंक्ति की कोशिश करने के लिए किया था कि कभी नहीं लेबल के रूप में के साथ इस्तेमाल किया जाएगा मानकों [:tb], लेकिन वह writing / rमें कई पंक्तियों को eading [rw] फ़ाइल पैरामीटर आमतौर पर द्वारा प्रश्न के बिना स्वीकार किया जाता है sedरों मैं एम्बेडेड के रूप में इतने लंबे समय परीक्षण किया है \newline w / एक \बैकस्लैश से बच गया है । फिर भी, मानक सीधे उस लेबल को निर्दिष्ट नहीं करता है और [rw] फ़ाइल मापदंडों को पाठ के लिए पहचान योग्य रूप से पार्स किया जाना चाहिएपैरामीटर और \nपहले दो के संबंध में ewlines का कोई उल्लेख नहीं करता है, सिवाय इसके कि यह उनका परिसीमन करता है।

...commands;[:trwb] parameter
...more;commands...

... या ...

sed -e '[:trwb] parameter' -e '...'

... जहां <space>ऊपर के लिए वैकल्पिक है [:tb]

और अंतिम...

...;address[!]{ ...function;commands...
};...more;commands....

... या ...

sed -e '...;address[!]{ ...function;commands...' -e '};...more;commands...'

... जहां उपर्युक्त आदेशों के किसी भी (छोड़कर :) भी कम से कम एक को स्वीकार पता और जो या तो एक हो सकता है /regexp /या एक लाइन नंबर और साथ नकार दिया गया हो सकता है !, लेकिन अगर एक से अधिक आदेश की एक एकल मूल्यांकन के लिए आवश्यक है पता तो {फ़ंक्शन संदर्भ }परिसीमन ब्रेसिज़ का उपयोग किया जाना चाहिए। एक फ़ंक्शन में कई \nईवलाइन सीमांकित कमांड शामिल हो सकते हैं , लेकिन प्रत्येक को ब्रेसिज़ के भीतर सीमांकित किया जाना चाहिए क्योंकि यह अन्यथा होगा।

और यह है कि पोर्टेबल sedस्क्रिप्ट कैसे लिखें ।


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