इस सवाल की टिप्पणियों में एक मामला सामने आया जहां विभिन्न सरल कार्यान्वयन काफी असहमत कार्यक्रम पर असहमत थे, और हम (या कम से कम मैं) यह निर्धारित करने में सक्षम नहीं थे कि इसके लिए वास्तव में विनिर्देश की आवश्यकता क्या है।
समस्या एक विलम्बित रेखा पर शुरू होने वाली श्रेणी का व्यवहार है:
1d;1,2d
क्या लाइन 2 को हटा दिया जाना चाहिए भले ही उस कमांड तक पहुंचने से पहले रेंज की शुरुआत को हटा दिया गया हो? मेरी शुरुआती उम्मीद बीएसडी sed के अनुरूप "नहीं" थी, जबकि GNU sed "हाँ" कहता है, और विनिर्देश पाठ की जाँच पूरी तरह से मामले को हल नहीं करती है।
मेरी अपेक्षा से मेल खाते हैं (कम से कम) macOS और Solaris sed
, और BSD sed
। असहमत हैं (कम से कम) जीएनयू और बिजीबॉक्स sed
, और यहां कई लोग हैं। पहले दो SUS- प्रमाणित हैं, जबकि अन्य संभावित रूप से अधिक व्यापक हैं। कौन सा व्यवहार सही है?
विनिर्देश पाठ दो पता श्रेणी के लिए कहते हैं:
तब सीड यूटिलिटी तब अनुक्रम में लागू होगी, जिनके कमांड अगले चक्र या क्विट शुरू होने तक, जिनके कमांड स्पेस पैटर्न का चयन करते हैं।
तथा
दो पतों वाला एक एडिटिंग कमांड पहले पैटर्न स्पेस से इनक्लूसिव रेंज का चयन करेगा, जो दूसरे पैटर्न से मेल खाने वाले अगले पैटर्न स्पेस के जरिए पहले एड्रेस से मैच करता है। [...] चयनित सीमा के बाद पहली पंक्ति से शुरू होकर, sed पहले पते के लिए फिर से दिखेगा। इसके बाद, इस प्रक्रिया को दोहराया जाएगा।
बेशक, लाइन 2 है भीतर , चाहे प्रारंभ बिंदु हटा दिया गया है, भले ही "पहले पैटर्न अंतरिक्ष कि अगले पैटर्न अंतरिक्ष दूसरे से मेल खाता है के माध्यम से पहली पते से मेल खाता से समावेशी रेंज"। दूसरी ओर, मैंने पहले d
चक्र में आगे बढ़ने की उम्मीद की और सीमा को शुरू करने का मौका नहीं दिया। UNIX ™ -certified कार्यान्वयन वही करता है जो मुझे उम्मीद थी, लेकिन संभवतः ऐसा नहीं है जो विनिर्देशन जनादेश।
कुछ इलस्ट्रेटिव एक्सपेरिमेंट फॉलो करते हैं, लेकिन अहम सवाल यह है कि डिलीट लाइन पर रेंज शुरू होने पर क्या करना चाहिए sed
?
प्रयोग और उदाहरण
समस्या का एक सरलीकृत प्रदर्शन यह है, जो लाइनों की अतिरिक्त प्रतियों को हटाने के बजाय प्रिंट करता है:
printf 'a\nb\n' | sed -e '1d;1,2p'
यह sed
इनपुट की दो लाइनें प्रदान करता है , a
और b
। कार्यक्रम दो काम करता है:
के साथ पहली पंक्ति हटाता है
1d
।d
आदेश होगापैटर्न स्पेस हटाएं और अगला चक्र शुरू करें। तथा
- 1 से 2 तक की पंक्तियों की सीमा का चयन करें और प्रत्येक पंक्ति को प्राप्त होने वाली स्वचालित छपाई के अलावा उन्हें स्पष्ट रूप से प्रिंट करता है। सीमा में शामिल एक पंक्ति इस प्रकार दो बार दिखाई देनी चाहिए।
मेरी अपेक्षा यह थी कि यह छपनी चाहिए
b
केवल, सीमा लागू नहीं होने के कारण क्योंकि 1,2
लाइन 1 के दौरान कभी नहीं पहुंचा जाता है (क्योंकि d
अगले चक्र / लाइन पर पहले से ही कूद गया है) और इसलिए सीमा शामिल करना कभी भी शुरू नहीं होता है, जबकि a
हटा दिया गया है। sed
मैकओएस और सोलारिस 10 के अनुरूप यूनिक्स एस इस उत्पादन का उत्पादन करते हैं, जैसा कि sed
सोलारिस और बीएसडी sed
में गैर-पॉसिक्स सामान्य रूप से करते हैं।
दूसरी ओर जीएनयू सेड, प्रिंट
b
b
यह दर्शाता है कि इसने रेंज की व्याख्या की है। यह POSIX मोड में होता है और नहीं भी। बिजीबॉक्स के सीड में समान व्यवहार होता है (लेकिन हमेशा समान व्यवहार नहीं होता है, इसलिए यह साझा कोड का परिणाम नहीं लगता है)।
के साथ आगे प्रयोग
printf 'a\nb\nc\nd\ne\n' | sed -e '2d;2,/c/p'
printf 'a\nb\nc\nd\ne\n' | sed -e '2d;2,/d/p'
यह पाता है कि यह एक हटाई गई रेखा पर शुरू होने वाली सीमा का इलाज करता प्रतीत होता है जैसे कि यह निम्न पंक्ति पर शुरू होता है । यह दृश्यमान है क्योंकि /c/
सीमा समाप्त करने के लिए मेल नहीं खाता है। /b/
रेंज शुरू करने का उपयोग करने के रूप में ही व्यवहार नहीं करता है 2
।
प्रारंभिक कार्य उदाहरण मैं उपयोग कर रहा था
printf '%s\n' a b c d e | sed -e '1{/a/d;};1,//d'
पहले /a/
मैच तक सभी लाइनों को हटाने के लिए एक तरीका के रूप में , भले ही वह पहली पंक्ति पर हो (जीएनयू sed किसके 0,/a/d
लिए उपयोग करेगा - यह उस का POSIX- संगत प्रतिपादन था)।
यह सुझाव दिया गया है कि इस के बजाय करने के लिए हटा देना चाहिए दूसरे का मैच /a/
है, जो प्रशंसनीय लगता है (अगर कोई दूसरा मैच है या पूरी फ़ाइल) पहली पंक्ति मैचों हैं - लेकिन फिर से, केवल जीएनयू sed कि नहीं करता है। दोनों macOS sed और सोलारिस की sed उपज
b
c
d
e
उस के लिए, जैसा कि मुझे उम्मीद थी (GNU sed अनअर्डिनेटेड रेंज को हटाने से खाली आउटपुट पैदा करता है; बिजीबॉक्स sed प्रिंट बस d
और e
, जो स्पष्ट रूप से गलत है कोई फर्क नहीं पड़ता)। आम तौर पर मुझे लगता है कि उनके पास होने के कारण प्रमाणन अनुरूपता परीक्षण का अर्थ है कि उनका व्यवहार सही है, लेकिन पर्याप्त लोगों ने सुझाव दिया है कि मुझे यकीन नहीं है, विनिर्देश पाठ पूरी तरह से आश्वस्त नहीं है, और परीक्षण सूट नहीं हो सकता है पूरी तरह से व्यापक।
स्पष्ट रूप से यह लिखने के लिए व्यावहारिक रूप से पोर्टेबल नहीं है कि आज कोड को असंगति दी गई है, लेकिन सैद्धांतिक रूप से यह एक अर्थ या दूसरे के साथ हर जगह समान होना चाहिए। मुझे लगता है कि यह एक बग है, लेकिन मुझे यह नहीं पता है कि इसे लागू करने के लिए कौन सा कार्यान्वयन है। मेरा विचार वर्तमान में यह है कि GNU और बिजीबॉक्स सेड का व्यवहार विनिर्देश के साथ असंगत है, लेकिन मुझे उस पर गलती हो सकती है।
यहाँ POSIX की क्या आवश्यकता है?
ed
,sed
पूरी तरह से दरकिनार ?