एक सिंहावलोकन कई उपयोगी की मौजूदा जवाब , से पूरित स्पष्टीकरण :
यहां के उदाहरण एक सरलीकृत उपयोग के मामले का उपयोग करते हैं: 'फू' शब्द को 'बार' के साथ केवल पहली मिलान पंक्ति में बदलें।
के उपयोग के कारण एएनएसआई सी उद्धृत तार ( $'...'
) नमूना इनपुट लाइनों प्रदान करने के लिए, bash
, ksh
, या zsh
शेल के रूप में माना जाता है।
sed
केवल GNU :
बेन हॉफस्टीन का अन्वेषक हमें दिखाता है कि GNU , POSIX विनिर्देश को एक विस्तार प्रदान करता है जिसके लिए निम्नलिखित 2-पता फ़ॉर्म की अनुमति देता है : ( यहाँ एक मनमाना नियमित अभिव्यक्ति का प्रतिनिधित्व करता है)।sed
0,/re/
re
0,/re/
रेगेक्स को बहुत पहले लाइन पर भी मैच करने की अनुमति देता है । दूसरे शब्दों में: ऐसा पता पहली पंक्ति से एक रेखा बनाएगा जिसमें पंक्ति और उस रेखा शामिल है जो मेल खाती है re
- चाहे re
वह पहली पंक्ति में हो या किसी भी बाद की रेखा पर।
- POSIX अनुरूप फार्म के साथ इस कंट्रास्ट
1,/re/
, जो एक सीमा बनाता है कि 1 लाइन से मैच के लिए और लाइन सहित कि मैचों re
पर बाद में लाइनों; दूसरे शब्दों में: यह पहली पंक्ति में होने वाले मैच की पहली घटना का पता नहीं लगाएगाre
और हाल ही में उपयोग किए गए रीगेक्स//
के पुन: उपयोग के लिए शॉर्टहैंड के उपयोग को भी रोकता है (अगला बिंदु देखें)। 1
यदि आप एक 0,/re/
पते s/.../.../
(प्रतिस्थापन) के साथ एक पते को जोड़ते हैं जो समान नियमित अभिव्यक्ति का उपयोग करता है , तो आपकी कमांड प्रभावी रूप से केवल पहली पंक्ति पर प्रतिस्थापन का प्रदर्शन करेगी जो मेल खाती है re
। सबसे हाल ही में लागू नियमित अभिव्यक्ति के पुन: उपयोग के लिए
sed
एक सुविधाजनक शॉर्टकट प्रदान करता है : एक खाली सीमांत जोड़ी//
,।
$ sed '0,/foo/ s//bar/' <<<$'1st foo\nUnrelated\n2nd foo\n3rd foo'
1st bar # only 1st match of 'foo' replaced
Unrelated
2nd foo
3rd foo
POSIX-features-only sed
जैसे BSD (macOS)sed
( GNU के साथ भी काम करेगा sed
):
चूंकि 0,/re/
इसका उपयोग नहीं किया जा सकता है और प्रपत्र 1,/re/
का पता नहीं चलेगा re
यदि यह पहली पंक्ति में होता है (ऊपर देखें), तो पहली पंक्ति के लिए विशेष हैंडलिंग आवश्यक है ।
मिखाइलव्स के जवाब में इस तकनीक का उल्लेख है, यहां एक ठोस उदाहरण दिया गया है:
$ sed -e '1 s/foo/bar/; t' -e '1,// s//bar/' <<<$'1st foo\nUnrelated\n2nd foo\n3rd foo'
1st bar # only 1st match of 'foo' replaced
Unrelated
2nd foo
3rd foo
ध्यान दें:
खाली रेगेक्स //
शॉर्टकट को यहां दो बार नियोजित किया गया है: एक बार सीमा के समापन बिंदु के लिए, और एक बार s
कॉल में; दोनों ही मामलों में, रेगेक्स foo
का पुन: उपयोग किया जाता है, जिससे हमें इसे डुप्लिकेट नहीं करना पड़ता है, जो छोटे और अधिक रखरखाव कोड दोनों के लिए बनाता है।
POSIX sed
को कुछ कार्यों के बाद वास्तविक नईलाइन्स की आवश्यकता होती है, जैसे कि लेबल के नाम पर या यहां तक कि इसके चूक के बाद भी, जैसा कि t
यहाँ है; रणनीतिक रूप से स्क्रिप्ट को कई -e
विकल्पों में विभाजित करना एक वास्तविक newlines का उपयोग करने का एक विकल्प है: प्रत्येक -e
स्क्रिप्ट को समाप्त करना जहां एक नई पंक्ति को सामान्य रूप से जाने की आवश्यकता होगी।
1 s/foo/bar/
foo
केवल 1 पंक्ति पर प्रतिस्थापित करता है, अगर वहाँ पाया जाता है। यदि हां, तो t
स्क्रिप्ट के अंत तक शाखाएं (रेखा पर शेष कमांड को छोड़ती हैं)। ( t
किसी लेबल पर फ़ंक्शन शाखाएं तभी होती हैं जब सबसे हालिया s
कॉल ने वास्तविक प्रतिस्थापन का प्रदर्शन किया हो; लेबल की अनुपस्थिति में, जैसा कि यहां है, स्क्रिप्ट का अंत शाखित है)।
जब ऐसा होता है, तो सीमा पता 1,//
, जो आम तौर पर लाइन 2 से शुरू होने वाली पहली घटना का पता लगाता है , मैच नहीं करेगा , और सीमा को संसाधित नहीं किया जाएगा, क्योंकि वर्तमान लाइन के पहले से ही पते का मूल्यांकन किया जाता है 2
।
इसके विपरीत, ऐसे 1 लाइन पर कोई मुकाबला नहीं है, तो 1,//
होगा प्रवेश किया, और सच पहला मैच मिल जाएगा।
शुद्ध प्रभाव जीएनयू साथ के रूप में ही है sed
की 0,/re/
केवल पहली घटना बदल दिया जाता है, चाहे वह 1 लाइन या किसी अन्य पर होता है:।
गैर-रेंज दृष्टिकोण
Potong के जवाब दर्शाता है पाश तकनीक है कि एक की जरूरत महसूस की बाईपास ; चूंकि वह GNU sed
सिंटैक्स का उपयोग करता है , यहाँ POSIX- आज्ञाकारी समकक्ष हैं :
लूप तकनीक 1: पहले मैच पर, प्रतिस्थापन प्रदर्शन करें, फिर एक लूप दर्ज करें जो बस शेष रेखाओं को प्रिंट करता है :
$ sed -e '/foo/ {s//bar/; ' -e ':a' -e '$!{n;ba' -e '};}' <<<$'1st foo\nUnrelated\n2nd foo\n3rd foo'
1st bar
Unrelated
2nd foo
3rd foo
केवल छोटी फ़ाइलों के लिए लूप तकनीक 2 : पूरे इनपुट को मेमोरी में पढ़ें, फिर उस पर एकल प्रतिस्थापन करें ।
$ sed -e ':a' -e '$!{N;ba' -e '}; s/foo/bar/' <<<$'1st foo\nUnrelated\n2nd foo\n3rd foo'
1st bar
Unrelated
2nd foo
3rd foo
1 1.61803 उदाहरण देता है कि क्या होता है 1,/re/
, इसके साथ और उसके बाद क्या होता है s//
:
- sed '1,/foo/ s/foo/bar/' <<<$'1foo\n2foo'
पैदावार $'1bar\n2bar'
; यानी, दोनों लाइनें अपडेट की गईं, क्योंकि लाइन नंबर 1
1 लाइन से मेल खाता है, और रेगेक्स /foo/
- रेंज का अंत - उसके बाद केवल अगली लाइन पर शुरू करने के लिए देखा जाता है । इसलिए, इस मामले में दोनों पंक्तियों का चयन किया जाता है, और s/foo/bar/
प्रतिस्थापन दोनों पर किया जाता है।
- sed '1,/foo/ s//bar/' <<<$'1foo\n2foo\n3foo'
विफल रहता है : sed: first RE may not be empty
(BSD / macOS) और sed: -e expression #1, char 0: no previous regular expression
(GNU) के साथ, क्योंकि, उस समय पहली पंक्ति पर कार्रवाई की जा रही है (लाइन संख्या 1
शुरू होने के कारण ), कोई भी रेगेक्स अभी तक लागू नहीं किया गया है, इसलिए//
कुछ भी संदर्भित नहीं करता है।
जीएनयू sed
के विशेष 0,/re/
सिंटैक्स के अपवाद के साथ , कोई भी रेखा जो लाइन नंबर से शुरू होती है , प्रभावी रूप से उपयोग को रोकती है //
।