Sed: हर दूसरे न्यूलाइन पर पैटर्न बदलें?


10

क्या sedहर दूसरी घटना पर पैटर्न को बदलने के लिए बताने का एक तरीका है ? या कम से कम हर दूसरी पंक्ति पर? (यकीन है कि यह एक स्क्रिप्ट के साथ संभव है, लेकिन मैं खुद से पूछ रहा था कि sedक्या ऐसा कर सकते हैं)।

संपादित करें

मुझे मिला

sed -e "s/pattern/replacement/g;n"

लेकिन इसने हर पहली घटना को प्रतिस्थापित किया, दूसरे को नहीं।

उदाहरण

इनपुट फ़ाइल:

I have a pattern in each line
Also the second line has the pattern
Another pattern here
And -- you guess it -- a pattern

वांछित उत्पादन:

I have a pattern in each line
Also the second line has the replacement
Another pattern here
And -- you guess it -- a replacement

जवाबों:


6

देख /programming/5858200/sed-replace-every-nth-occurrence

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


1
वहाँ sed -e 'n;s/2004-2009/6e législature/g'जो मैंने सीखा है उसका उपयोग करके मैंने अपनी समस्या का समाधान किया।
मैथ्यू रीगलर

1
यह हर दूसरी घटना नहीं होगी, यह हर दूसरी पंक्ति में आपके पैटर्न की खोज करेगी । यानी पहली, तीसरी, 5 वीं, 7 वीं आदि लाइनों को छोड़ें। बेशक, यह अभी भी आपके विशेष दस्तावेज़ के लिए काम कर सकता है।
कैस

हाँ मुझे पता है। वास्तव में मुझे यही चाहिए था।
मैथ्यू रीगलर

14
sed 's/pattern/replacement/2'

पैटर्न है कि हर लाइन पर दूसरी घटना की जगह लेगा।


यदि आपके पास GNU है sed:

sed '1~2N ; s/pattern/replacement/2'

लाइन एक से शुरू होकर 1, इसके बाद की लाइन पैटर्न स्पेस में जुड़ जाएगी Nफिर sकमांड पैटर्न की दूसरी घटना की जगह लेगी। फिर sedदो लाइनों को नीचे ले जाएगा ~2और दोहराएगा।


मुझे दूसरा नहीं बल्कि हर सेकंड चाहिए।
Matthieu Riegler

मेरे पास प्रति पंक्ति एक पैटर्न है। यह काम नहीं करेगा।
मैथ्यू रीगलर

यह जानकर अच्छा लगा कि पहले। तो पैटर्न लाइन एक, दो, तीन और चार (आदि) पर होता है, और आप पैटर्न को लाइन दो, चार, आदि पर बदलना चाहते हैं?
12

एक छोटा विकल्प हो सकता है code(sed '1 ~ 2s / पैटर्न / प्रतिस्थापन /')
jaap

2

सरल व्याख्या:

पहली पंक्ति में जिसमें PATTERN की कम से कम एक घटना शामिल है आप इसे अनदेखा करना चाहते हैं और लाइन को प्रिंट करना चाहते हैं। दूसरी पंक्ति में जिसमें PATTERN की कम से कम एक घटना शामिल है, आप PATTERN के पहले उदाहरण को रिप्लेसमेंट के साथ बदलना चाहते हैं। तीसरी पंक्ति में जिसमें PATTERN की कम से कम एक घटना शामिल है, जिसे आप रेखा के रूप में प्रिंट करना चाहते हैं। चौथी पंक्ति में जिसमें PATTERN की कम से कम एक घटना शामिल है, आप PATTERN के पहले उदाहरण को रिप्लेसमेंट के साथ बदलना चाहते हैं। और इसी तरह। जो लाइनें PATTERN से मेल नहीं खाती हैं, उन्हें परिवर्तन के बिना मुद्रित किया जाना चाहिए।

यह आसानी से सैड के साथ किया जा सकता है जैसे:

sed -e '/PATTERN/ { :inside' -e 'n;s//REPLACEMENT/;t' -e 'b inside' -e '}'

या, कम व्हाट्सएप और एक छोटे लेबल के साथ:

sed -e '/PATTERN/{:i' -e 'n;s//REPLACEMENT/;t' -e 'b i' -e '}'

संपादित करें: मैं बस सवाल फिर से पढ़ता हूं और कठिन व्याख्या करता हूं:

पूरे दस्तावेज में PATTERN की दूसरी घटना को रिप्लेसमेंट के साथ बदलें, चाहे वह पहली घटना के समान रेखा पर हो या न हो। पहली और तीसरी घटनाओं को अनछुए छोड़ दें। आदि।

मेरा मानना ​​है कि यह सेड के साथ भी किया जा सकता है, हालांकि यह बहुत पेचीदा मामला है और मेरा मानना ​​है कि यह प्रयोग किए जाने वाले नियमित अभिव्यक्ति पर निर्भर है। मैं कुछ बाहर काम करने और इसे पोस्ट करने की कोशिश करूंगा, लेकिन मैं इस जवाब को अभी के लिए सरल संस्करण के साथ खड़ा होने दूंगा।


अपने tइस्ट को q{ sed '...'; cat; } <input
यूटिट से

1

आप बहुत करीब थे, बस पहली पंक्ति छोड़ें:

sed '1n;s/pattern/replacement/;n'

awkइस मामले में बेहतर उपकरण क्यों होना चाहिए ?


0

एक पंक्ति के भीतर एक प्रतीक पैटर्न: sed 's / ([[a] *) a / \ 1c / g'

प्रत्येक दूसरा पैटर्न (प्रति पंक्ति केवल एक पैटर्न मैच दिखाई दे सकता है। यदि प्रति पंक्ति दो या दो से अधिक मैच दिखाई देंगे, तो केवल दूसरा एक पैटर्न होगा)

echo -e "test\nreplace_me\ntest\ntest\nreplace_me\nreplace_me\nreplace_me" | \
sed '/replace_me/{:a;N;/replace_me.*replace_me/!Ta;s/replace_me/replaced/2;}'
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.