OSX एक निश्चित लाइन पर सम्मिलित करता है


24

इसलिए मैं थोड़ी देर के लिए linux पर 'sed' का उपयोग कर रहा हूं, लेकिन OSX पर 'POSIX sed' और 'GNU sed' में बहुत कम अंतर होने के कारण इसे इस्तेमाल करने में थोड़ी कठिनाई हुई है। वर्तमान में मैं निश्चित पंक्ति संख्या के बाद पाठ की एक पंक्ति सम्मिलित करने के लिए संघर्ष कर रहा हूं। (इस मामले में, पंक्ति ४)

Linux पर मैं कुछ ऐसा करूँगा:

sed --in-place "4 a\  mode '0755'" file.txt

तो OSX पर मैंने यह कोशिश की:

sed -i "" "4 a\ mode '0755'" file.txt

हालाँकि यह मुझे 'कमांड के अंत में' के बाद एक अतिरिक्त अक्षर देता है। किसी भी विचार यहाँ क्या गलत है? क्या मेरे पास टाइपो है? या मैं सेड के संस्करणों के बीच एक और अंतर नहीं समझ रहा हूं?


2
MacOS 10.6.8 पर काम नहीं करने के लिए इसकी पुष्टि कर सकते हैं। डेबियन 6.0.3 पर ठीक काम करता है।
tink

जवाबों:


24

कड़ाई से बोलने के बाद, POSIX विनिर्देश केsed लिए एक नई पंक्ति की आवश्यकता होती है a\:

[1addr]a\
text

मानक आउटपुट पर पाठ लिखें जैसा कि पहले बताया गया है।

यह एक-लाइनर्स एक दर्द का एक सा है, जो शायद निम्नलिखित के लिए कारण है लेखन बनाता है जीएनयू विस्तार करने के लिए a, iऔर cकमांड:

GNU एक्सटेंशन के रूप में, अगर aऔर न्यूलाइन के बीच एक व्हाट्सएप- \सीक्वेंस के अलावा अन्य है , तो इस लाइन का टेक्स्ट, पहले गैर-व्हाट्सएप कैरेक्टर पर शुरू होता है a, जिसे टेक्स्ट ब्लॉक की पहली लाइन के रूप में लिया जाता है । (यह एक-लाइन ऐड स्क्रिप्टिंग में सरलीकरण को सक्षम बनाता है।) यह एक्सटेंशन कमांड iऔर cकमांड के साथ भी काम करता है ।

इस प्रकार, अपने sedसिंटैक्स के साथ पोर्टेबल होने के लिए , आपको a\किसी तरह के बाद एक नई पंक्ति को शामिल करना होगा । सबसे आसान तरीका सिर्फ एक उद्धृत न्यूलाइन डालना है:

$ sed -e 'a\
> text'

(जहां $और >शेल प्रॉम्प्ट हैं)। यदि आप पाते हैं कि एक दर्द, bash[1] में $' 'सी-स्टाइल डालने के लिए वाक्य रचना है, तो बस उपयोग करें

sed -e 'a\'$'\n''text'

[1] और mksh (r39b +) और कुछ नॉन-बैश बॉर्न शेल (उदाहरण के लिए, FreeBSD 9+ में बिन / श)


बहुत जानकारीपूर्ण उत्तर। वाक्यविन्यास उद्धृत करने वाले बैश पर संकेत के लिए धन्यवाद।
cjackson

14

जैसा कि इस उत्तर में वर्णित है , यह sed कमांड जैसे iऔर aकई -e "..."क्लॉज का उपयोग करते समय मददगार होता है । इनमें से प्रत्येक खंड को नए सिरे से अलग किया जाना समझा जाएगा। iऔर aआदेशों का उपयोग करने में इनलाइन स्क्रिप्ट अन्यथा sed (वे एक बहु sed स्क्रिप्ट फ़ाइल में इस्तेमाल के लिए डिजाइन कर रहे हैं का उपयोग कर लागू मुश्किल है sed -f file ...)। ऐसा लगता है कि आप एक -eखंड के अंत में प्रस्तुत किए गए निहित न्यूलाइन का उपयोग अलग करने के लिए नहीं कर सकते हैं a\और पाठ की लाइन को जोड़ा जाना है। लेकिन आप इसका उपयोग उस पाठ की रेखा को समाप्त करने के लिए कर सकते हैं जिसे जोड़ा जाना है।

इस विशिष्ट मामले में, आप जो करने की कोशिश कर रहे हैं वह वास्तव में एक -e ...खंड के साथ पूरा हो सकता है । आपको बस aकमांड का सही उपयोग करना है। POSIX मानक के अनुसार, aइसके बाद a की \आवश्यकता होती है, फिर एक नई पंक्ति का पालन करना पड़ता है, फिर अगली पंक्ति के शेष भाग को सम्मिलित किया जाएगा (जब तक कि एक नई पंक्ति या -eखंड का अंत नहीं हो जाता )। तो आप कर सकते हैं:

sed -i "" -e $'4 a\\\n'"mode '0755'" file.txt

2
यदि आप यह जानना चाहते हैं कि आप जिन सुविधाओं पर भरोसा कर रहे हैं, वे ग्नू- आईएमएस हैं, तो यह पृष्ठ मदद कर सकता है: wiki.alpinelinux.org/wiki/Regex । यह सिर्फ रेगेक्स सुविधाओं तक सीमित है, हालांकि; अन्य सेड कमांड नहीं।
डब्यूजिम

5

जीएनयू sed आमतौर पर POSIX sed की तुलना में बहुत अधिक उपयोग किया जाता है, उदाहरण / ट्यूटोरियल जो मैंने वैसे भी उपयोग किया है, के आधार पर।

मैंने पाया है कि मेरे द्वारा उपयोग की जाने वाली किसी भी OSX मशीन पर GNU सेड को स्थापित करना बहुत आसान है। यदि आप रुचि रखते हैं, तो ऐसा करने का सबसे अच्छा तरीका होमब्रे के माध्यम से इसे स्थापित करना है ।

आप या तो बस कर सकते हैं $ brew install gnu-sed, या सभी के साथ सामान्य जीएनयू उपयोगिताओं को प्राप्त कर सकते हैं $ brew install coreutils

तब जब आप dateकिसी अन्य प्रोग्राम के साथ एक सिंटैक्स समस्या में भाग लेते हैं और आप बस GNU संस्करण का उपयोग कर सकते हैं। आखिरकार मैंने सिर्फ यह निर्णय लिया कि हमेशा जीएनयू संस्करणों का उपयोग करना आसान था और उन्हें सिस्टम संस्करणों की तुलना में पहले से रखा गया था PATH


5

पर्ल ऐसे प्लेटफॉर्म पर निर्भर GNU बनाम नॉन-जीएनयू बनाम "प्रोप्राइटरी" आइडिओसिंक्राइसिस से पीड़ित नहीं है। तुम यह कर सकते थे:

perl -ni.old -e 'print;if ($.==4) {print "mode 0755\n"}' file

-n' option creates a loop that reads every line of the input file. Unlike its cousin-P (not used here) it doesn't automatically print every line read. Theमैं invokes in-place replacement. The argument toमैं (viz. ".old") can be dropped or changed. It leaves a backup of the unmodified file. The -eस्क्रिप्ट की शुरुआत का संकेत।

$.लाइन नंबर को दर्शाता है, लाइन-1 के साथ शुरुआत। इस प्रकार कमांड लाइन 'फाइल' पढ़ती है और जब लाइन-संख्या 4 के बराबर होती है, तो यह उस रेखा को प्रिंट करती है, जिसके बाद आप जो भी इंजेक्शन लगाना चाहते हैं।

मैं यह जोड़ने की जल्दबाजी करूँगा कि पर्ल अपनी जड़ें sed, AWK और C पर छोड़ देता है, इसलिए सरल प्रतिस्थापन के लिए वाक्यविन्यास, आदि बहुत ही कठिन सीखने की अवस्था नहीं है।


अच्छा जवाब! लेकिन आप इसे थोड़ा सरल कर सकते हैं। इस कोशिश perl -wlpi.old -e 'print "mode 0755" if $. == 5' file.txt:। -pस्विच अच्छी तरह से यहां काम करता है (क्योंकि हम हर पंक्ति प्रिंट करना चाहते हैं); हमें " लाइन 4 के बाद प्रिंटिंग" से लॉजिक को " लाइन 5 से पहले प्रिंटिंग" में बदलना होगा । और -lस्विच इसे बनाता है ताकि "\ n" हर के साथ स्वचालित रूप से प्रिंट हो printजाए, इसलिए आपको इसे स्वयं प्रिंट करने की आवश्यकता नहीं है।
जेएल
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.