sed
BSD / macOS Sed बनाम GNU Sed बनाम POSIX Sed विनिर्देश
खोज…
परिचय
@ SnoringFrog के विषय-निर्माण अनुरोध से उद्धृत करने के लिए:
"सेड का उपयोग करने वाले सबसे बड़े गोच में से एक स्क्रिप्ट है जो विफल हो जाती है (या अप्रत्याशित तरीके से सफल होती है) क्योंकि उन्हें एक के लिए लिखा गया था और दूसरे को नहीं। अधिक बड़े अंतर का सरल रन-डाउन अच्छा होगा।"
टिप्पणियों
macOS , sed
[1] के BSD संस्करण का उपयोग करता है, जो कि Linux distros के साथ आने वाले GNU sed
संस्करण से कई मामलों में भिन्न होता है।
उनका सामान्य भाजक POSIX द्वारा कार्यशील कार्यक्षमता है: POSIX sed
युक्ति देखें।
सबसे पोर्टेबल दृष्टिकोण केवल POSIX सुविधाओं का उपयोग करना है , जो, हालांकि, कार्यक्षमता को सीमित करता है :
विशेष रूप से, POSIX निर्दिष्ट केवल बुनियादी नियमित अभिव्यक्ति है, जो कई सीमाएं हैं के लिए समर्थन (जैसे, के लिए कोई समर्थन
|
(सब पर प्रत्यावर्तन), के लिए कोई सीधा समर्थन+
और?
) और विभिन्न बचने आवश्यकताओं।- कैविएट: GNU
sed
(बिना-r
), सपोर्ट करता है\|
,\+
और\?
, जो POSIX- अनुरूप नहीं है; उपयोग--posix
अक्षम करने के लिए (नीचे देखें)।
- कैविएट: GNU
केवल POSIX सुविधाओं का उपयोग करने के लिए :
(दोनों संस्करण): केवल
-n
और-e
विकल्पों का उपयोग करें (विशेष रूप से, विस्तारित नियमित अभिव्यक्तियों के लिए समर्थन चालू करने के लिए-E
or-r
का उपयोग न करें)जीएनयू
sed
: ऐड विकल्प--posix
POSIX-केवल कार्यक्षमता सुनिश्चित करने के (आप सख्ती से इस जरूरत नहीं है, लेकिन इसके बिना आप अनजाने का उपयोग कर गैर POSIX देख के बिना सुविधाओं अंत सकता है, चेतावनी:--posix
ही नहीं POSIX अनुरूप )POSIX- केवल सुविधाओं का उपयोग करने का मतलब है सख्त स्वरूपण आवश्यकताएं (GNU
sed
में उपलब्ध कई प्रकार की उपयुक्तताएँ):- नियंत्रण-वर्ण अनुक्रम जैसे कि
\n
और\t
आमतौर पर समर्थित नहीं होते हैं। - लेबल और ब्रांचिंग कमांड (जैसे,
b
) को एक अलग-e
विकल्प के माध्यम से एक वास्तविक न्यूलाइन या निरंतरता द्वारा पालन किया जाना चाहिए। - जानकारी के लिए नीचे देखें।
- नियंत्रण-वर्ण अनुक्रम जैसे कि
हालाँकि, दोनों संस्करण POSIX मानक के लिए एक्सटेंशन लागू करते हैं:
- वे किस विस्तार को लागू करते हैं (GNU
sed
अधिक)। - यहां तक कि उन एक्सटेंशनों को भी वे दोनों आंशिक रूप से सिंटैक्स में लागू करते हैं ।
यदि आपको BOTH प्लेटफार्मों (मतभेदों की चर्चा) का समर्थन करने की आवश्यकता है:
असंगत विशेषताएं:
तर्क के बिना
-i
विकल्प का उपयोग (बैकअप के बिना इन-प्लेस अद्यतन) असंगत है:- BSD
sed
: MUST उपयोग-i ''
- GNU
sed
: MUST का उपयोग सिर्फ-i
(समतुल्य:-i''
) - उपयोग-i ''
नहीं करता है।
- BSD
-i
समझदारी से GNUsed
में प्रति-इनपुट-फ़ाइल लाइन नंबरिंग और BSDsed
(जैसे FreeBSD 10 पर) के हाल के संस्करणों को चालू करता है, लेकिन MacOS पर 10.12 के रूप में नहीं है ।
ध्यान दें कि-i
के अभाव में सभी संस्करण संख्या रेखाएँ संचयी रूप से इनपुट फ़ाइलों में हैं।यदि अंतिम इनपुट लाइन में अनुगामी नई रेखा नहीं है (और मुद्रित है):
- BSD
sed
: हमेशा आउटपुट पर एक नई लाइन जोड़ता है , भले ही इनपुट लाइन एक में समाप्त न हो। - GNU
sed
: ट्रेलिंग-न्यूलाइन स्टेटस को संरक्षित करता है , अर्थात, यह एक नईलाइन तभी जोड़ता है जब इनपुट लाइन एक में समाप्त हो जाती है।
- BSD
सामान्य विशेषताएं:
- आप अपने प्रतिबंधित करते हैं
sed
क्या बीएसडी पर ऐसी स्क्रिप्टsed
का समर्थन करता है, वे आम तौर जीएनयू में काम करेंगेsed
भी - प्लेटफ़ॉर्म-विशिष्ट का उपयोग करने का उल्लेखनीय अपवाद के साथ regex सुविधाओं बढ़ाया-E
। जाहिर है, आप उन एक्सटेंशनों को भी छोड़ देंगे जो GNU संस्करण के लिए विशिष्ट हैं। अगला भाग देखें
- आप अपने प्रतिबंधित करते हैं
बीएसडी संस्करण की सख्त आवश्यकताओं द्वारा संचालित क्रॉस-प्लेटफ़ॉर्म समर्थन (ओएस एक्स / बीएसडी, लिनक्स) के लिए दिशानिर्देश :
ध्यान दें कि कि shorthands MacOS और लिनक्स कभी कभी के बीएसडी और GNU संस्करणों का उल्लेख करने के लिए नीचे दिए गए उपयोग किया जाता है sed
, क्रमशः, क्योंकि वे एक मंच पर शेयर संस्करण हैं। हालांकि, sed
पर जीएनयू sed
को स्थापित करना संभव है, उदाहरण के लिए, brew install gnu-sed
साथ होमब्रे का उपयोग करना।
नोट : जब -r
और -E
झंडे का उपयोग किया जाता है ( विस्तारित रेगेक्स) को छोड़कर , राशि के नीचे दिए गए निर्देशों को POSIX-compliant sed
स्क्रिप्ट लिखने के लिए।
POSIX अनुपालन के लिए, आपको अपने आप को POSIX BREs ( मूल नियमित अभिव्यक्ति) तक सीमित करना होगा, जो कि, दुर्भाग्य से, जैसा कि नाम से पता चलता है, काफी बुनियादी है।
कैविएट : यह मत मानो कि\|
,\+
और\?
समर्थित हैं: जबकि GNUsed
उनका समर्थन करता है (जब तक कि--posix
का उपयोग नहीं किया जाता है), BSDsed
नहीं करता - ये सुविधाएँ POSIX- अनुरूप नहीं हैं।
जबकि\+
और\?
POSIX- अनुरूप फैशन में अनुकरण किया जा सकता है :
\{1,\}
लिए\+
,
\{0,1\}
लिए\?
,
\|
(वैकल्पिक) दुर्भाग्य से नहीं कर सकते ।अधिक शक्तिशाली नियमित अभिव्यक्तियों के लिए, ERE ( विस्तारित नियमित अभिव्यक्ति ) का समर्थन करने के लिए
-E
(बल्कि-r
) का उपयोग करें (GNUsed
दस्तावेज़-E
नहीं करता है, लेकिन यह उर्फ-r
रूप में वहां काम करता है; BSDsed
का नया संस्करण; , जैसे कि FreeBSD 10 पर, अब सपोर्ट-r
भी करता है, लेकिन 10.12 के रूप में macOS संस्करण नहीं है )।
चेतावनी: भले ही के उपयोग-r
/-E
का मतलब है कि अपने आदेश नहीं POSIX अनुरूप परिभाषा से है, तो आप अभी भी अपने आप तक सीमित करना होगा POSIX eres (नियमित अभिव्यक्ति बढ़ाया गया) । अफसोस की बात है, इसका मतलब है कि आप कई उपयोगी निर्माणों का उपयोग करने में सक्षम नहीं होंगे, विशेष रूप से:- शब्द-सीमा के दावे, क्योंकि वे प्लेटफ़ॉर्म-विशिष्ट हैं (उदाहरण के लिए, लिनक्स पर
\<
, ओएस एक्स पर[[:<]]
। - नियमित अभिव्यक्ति के अंदर वापस संदर्भ (के रूप में कब्जा-समूह मैचों के लिए "वापस संदर्भ" के प्रतिस्थापन स्ट्रिंग में करने का विरोध किया
s
फ़ंक्शन कॉल), क्योंकि बीएसडीsed
विस्तारित regexes में उन्हें समर्थन नहीं करता है (लेकिन, दिलचस्प, में करता है बुनियादी लोग, जहां वे POSIX- जनादेश हैं)।
- शब्द-सीमा के दावे, क्योंकि वे प्लेटफ़ॉर्म-विशिष्ट हैं (उदाहरण के लिए, लिनक्स पर
नियंत्रण-वर्ण से बचने के क्रम जैसे
\n
और\t
:Regexes में (लाइन चयन के लिए पैटर्न और
s
फ़ंक्शन के लिए पहला तर्क), मान लें कि केवल\n
को एस्केप अनुक्रम के रूप में मान्यता प्राप्त है (शायद ही कभी उपयोग किया जाता है, क्योंकि पैटर्न स्पेस आमतौर पर एक एकल लाइन है (बिना समाप्ति के\n
), लेकिन एक वर्ण वर्ग के अंदर नहीं, ताकि, उदाहरण के लिए,[^\n]
काम नहीं करता है; (यदि आपके इनपुट में कोई नियंत्रण वर्ण नहीं है।\t
, आप[^\n]
[[:print:][:blank:]]
[^\n]
साथ[[:print:][:blank:]]
[^\n]
का अनुकरण कर सकते हैं[[:print:][:blank:]]
, अन्यथा, जोड़ नियंत्रण वर्ण में के रूप में शाब्दिक [2]) - आम तौर पर, शाब्दिक रूप में नियंत्रण वर्ण, या तो spliced में एएनएसआई सी उद्धृत तार (के माध्यम से शामिल हैं जैसे,।$'\t'
में) गोले है कि यह (समर्थनbash,
ksh,zsh
), या आदेश प्रतिस्थापन के माध्यम से उपयोग कर रहाprintf
(जैसे,"$(printf '\t')"
)।- केवल लिनक्स:
sed 's/\t/-/' <<<$'a\tb' # -> 'a-b'
- OSX और Linux:
sed 's/'$'\t''/-/' <<<$'a\tb' # ANSI C-quoted string
sed 's/'"$(printf '\t')"'/-/' <<<$'a\tb' # command subst. with printf
- केवल लिनक्स:
s
कमांड के साथ उपयोग किए जाने वाले प्रतिस्थापन तारों में , मान लें कि कोई नियंत्रण-चरित्र से बचने के क्रम का समर्थन किया जाता है , इसलिए, फिर से, नियंत्रण वर्ण शामिल करें। ऊपर के रूप में, शाब्दिक के रूप में।- केवल लिनक्स:
sed 's/-/\t/' <<<$'ab' # -> 'a<tab>b'
- macOS और लिनक्स:
sed 's/-/'$'\t''/' <<<'a-b'
sed 's/-/'"$(printf '\t')"'/' <<<'a-b'
- केवल लिनक्स:
i
औरa
फ़ंक्शन के लिए पाठ तर्क के लिए Ditto: नियंत्रण-वर्ण अनुक्रम का उपयोग न करें - नीचे देखें।
लेबल और ब्रांचिंग : लेबल के साथ-साथ
b
औरt
फ़ंक्शन के लिए लेबल-नाम तर्क का शाब्दिक न्यूलाइन या एक स्पाइसिल-इन$'\n'
द्वारा किया जाना चाहिए । वैकल्पिक रूप से, एकाधिक-e
विकल्पों का उपयोग करें और लेबल नाम के बाद प्रत्येक अधिकार को समाप्त करें।- केवल लिनक्स:
sed -n '/a/ bLBL; d; :LBL p' <<<$'a\nb' # -> 'a'
- macOS और लिनक्स:
- EITHER (वास्तविक नए अंक):
sed -n '/a/ bLBL d; :LBL p' <<<$'a\nb'
- या (spliced-in
$\n
उदाहरण):
sed -n '/a/ bLBL'$'\n''d; :LBL'$'\n''p' <<<$'a\nb'
- या (एकाधिक
-e
विकल्प):
sed -n -e '/a/ bLBL' -e 'd; :LBL' -e 'p' <<<$'a\nb'
- EITHER (वास्तविक नए अंक):
- केवल लिनक्स:
कार्य
i
औरa
डालने / पाठ जोड़कर के लिए: द्वारा समारोह का अनुपालन करें\
, एक शाब्दिक न्यू लाइन या एक spliced-इन करके या तो पीछा$'\n'
पाठ तर्क निर्दिष्ट करने से पहले।- केवल लिनक्स:
sed '1 i new first line' <<<$'a\nb' # -> 'new first line<nl>a<nl>b'
- OSX और Linux:
sed -e '1 i\'$'\n''new first line' <<<$'a\nb'
- ध्यान दें:
- बिना
-e
, पाठ तर्क अनावश्यक रूप से macOS (बग?) पर आउटपुट पर न्यूलाइन-टर्मिनेटेड नहीं है। - पाठ तर्क में नियंत्रण-चरित्र से बचने जैसे
\n
और\t
का उपयोग न करें , क्योंकि वे केवल लिनक्स पर समर्थित हैं। - यदि पाठ तर्क में वास्तविक आंतरिक newlines हैं, तो उन्हें
\
हटाएं। - यदि आप पाठ तर्क के बाद अतिरिक्त कमांड रखना चाहते हैं, तो आपको इसे (unescaped) न्यूलाइन (चाहे शाब्दिक या spliced) के साथ समाप्त करना होगा, या एक अलग
-e
विकल्प के साथ जारी रखना चाहिए (यह एक सामान्य आवश्यकता है जो सभी संस्करणों पर लागू होती है) ।
- बिना
- केवल लिनक्स:
अंदर समारोह सूचियों (कई समारोह में संलग्न कॉल
{...}
), सुनिश्चित करें कि पिछले समारोह समाप्त करने के लिए बंद करने से पहले, हो}
के साथ,;
।- केवल लिनक्स:
-
sed -n '1 {p;q}' <<<$'a\nb' # -> 'a'
-
- macOS और लिनक्स:
-
sed -n '1 {p;q;}' <<<$'a\nb'
-
- केवल लिनक्स:
GNU sed
विशिष्ट विशेषताएं BSD sed
पूरी तरह गायब हैं:
यदि आपको दोनों प्लेटफ़ॉर्म का समर्थन करने की आवश्यकता है तो GNU सुविधाएँ आपको याद आएंगी:
विभिन्न रेगेक्स-मिलान और प्रतिस्थापन विकल्प (दोनों लाइन चयन के लिए पैटर्न और
s
फ़ंक्शन के लिए पहला तर्क):- केस-इनसेन्सिटिव रेगेक्स मिलान के लिए
I
विकल्प (अविश्वसनीय रूप से, BSDsed
इसका समर्थन नहीं करता है)। - बहु-लाइन मिलान के लिए
M
विकल्प (जहाँ^
/$
प्रत्येक पंक्ति के प्रारंभ / अंत से मेल खाता है) - अतिरिक्त विकल्पों के लिए जो
s
फ़ंक्शन के लिए विशिष्ट हैं, https://www.gnu.org/software/sed/manual/rew.html#The-_0022s_0022- कोमांड देखें
- केस-इनसेन्सिटिव रेगेक्स मिलान के लिए
बच के क्रम
जैसे प्रतिस्थापन से संबंधित भागने दृश्यों
\u
के प्रतिस्थापन बहस मेंs///
समारोह है कि हेरफेर सबस्ट्रिंग अनुमति देते हैं, सीमा के भीतर; उदाहरण के लिए,sed 's/^./\u&/' <<<'dog' # -> 'Dog'
- देखें http://www.gnu.org/software/rew/manual/sed.html#The-_0022s_0022 -Commandनियंत्रण-चरित्र से बचने के क्रम:
\n
,\t
, ..., कोडपॉइंट-आधारित पलायन के अलावा; उदाहरण के लिए, निम्नलिखित सभी भाग (हेक्स।, ऑक्टल, दशमलव) एक एकल उद्धरण ('
):\x27
,\o047
,\d039
- https://www.gnu.org/software/sed/manual/ देखें sed.html # पलायन
जैसे पता एक्सटेंशन
first~step
हर कदम-वें लाइन, मैच के लिएaddr, +N
मैच के लिए एन लाइनों निम्नलिखितaddr
देखते हैं -, ... http://www.gnu.org/software/sed/manual/sed। एचटीएमएल # पतों
[१] macOS sed
संस्करण अन्य BSD जैसी प्रणालियों जैसे FreeBSD और PC-BSD के संस्करण से पुराना है। दुर्भाग्य से, इसका मतलब है कि आप यह नहीं मान सकते हैं कि जो सुविधाएँ FreeBSD में काम करती हैं, उदाहरण के लिए, macOS पर [वही] काम करेंगी।
[2] एएनएसआई सी उद्धृत स्ट्रिंग $'\001\002\003\004\005\006\007\010\011\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037\177'
में \n
(और NUL) को छोड़कर सभी ASCII नियंत्रण वर्ण हैं, इसलिए आप इसे [:print:]
साथ संयोजन में उपयोग कर सकते हैं [^\n]
बहुत मजबूत अनुकरण के लिए:
'[[:print:]'$'\001\002\003\004\005\006\007\010\011\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037\177'']
सभी नई सूचियों को टैब से बदलें
नोट: संक्षिप्तता के लिए, कमांड यहां-स्ट्रिंग्स ( <<<
) और ANSI C- उद्धृत स्ट्रिंग्स ( $'...'
) का उपयोग करते हैं । ये दोनों शेल फीचर bash
, ksh
और zsh
में काम करते हैं।
# GNU Sed
$ sed ':a;$!{N;ba}; s/\n/\t/g' <<<$'line_1\nline_2\nline_3'
line_1 line_2 line_3
# BSD Sed equivalent (multi-line form)
sed <<<$'line_1\nline_2\nline_3' '
:a
$!{N;ba
}; s/\n/'$'\t''/g'
# BSD Sed equivalent (single-line form, via separate -e options)
sed -e ':a' -e '$!{N;ba' -e '}; s/\n/'$'\t''/g' <<<$'line 1\nline 2\nline 3'
बीएसडी सेड नोट:
लेबल को समाप्त करने की आवश्यकता पर ध्यान दें
:a
(:a
) और शाखाएं कमांड (ba
) या तो वास्तविक नईलाइनों के साथ या अलग-e
अलग विकल्पों के साथ।चूंकि इस तरह के रूप में नियंत्रण-चरित्र भागने दृश्यों
\t
प्रतिस्थापन स्ट्रिंग में समर्थित नहीं हैं, एक एएनएसआई सी उद्धृत टैब शाब्दिक प्रतिस्थापन स्ट्रिंग में spliced है।
( रेगेक्स भाग में, बीएसडी सेड केवल एक एस्केप अनुक्रम के रूप में\n
पहचानता है)।
फ़ंक्शन 'a' के साथ शाब्दिक पाठ को एक पंक्ति में जोड़ें
नोट: संक्षिप्तता के लिए, कमांड यहां-स्ट्रिंग्स ( <<<
) और ANSI C- उद्धृत स्ट्रिंग्स ( $'...'
) का उपयोग करते हैं । ये दोनों शेल फीचर bash
, ksh
और zsh
में काम करते हैं।
# GNU Sed
$ sed '1 a appended text' <<<'line 1'
line 1
appended text
# BSD Sed (multi-line form)
sed '1 a\
appended text' <<<'line 1'
# BSD Sed (single-line form via a Bash/Ksh/Zsh ANSI C-quoted string)
sed $'1 a\\\nappended text' <<<'line 1'
ध्यान दें कि कैसे बीएसडी बीज को पाठ को पास करने के लिए एक वास्तविक न्यूलाइन द्वारा एक \
_ की आवश्यकता होती है।
वही संबंधित i
(सम्मिलित करें) और c
(हटाएं और सम्मिलित करें) कार्यों पर लागू होता है।