पुनरावृत्ति को कैसे सेड के साथ अक्षर बदलें?


13

क्या पुन: उसी अनुक्रम पर पुनरावृति के बिना किसी वर्ण अनुक्रम के पुनरावृत्तियों को प्रतिस्थापित करना संभव है?

sedनिम्नलिखित परिदृश्य में एक प्रदर्शन करके मैं उल्लेखित आउटपुट प्राप्त कर सकता हूं।

$ echo XX | sed -e 's/XX/XoX/g'
XoX  
$ echo XXX | sed -e 's/XX/XoX/g'
XoXX  
$ echo XXXX | sed -e 's/XX/XoX/g'
XoXXoX  

हालाँकि, मैं आउटपुट को निम्न व्यवहार का पालन करने की उम्मीद कर रहा हूं।

इनपुट:

XX
XXX
XXXX

अपेक्षित उत्पादन:

XoX
XoXoX
XoXoXoX

क्या अकेले sed के साथ अपेक्षित व्यवहार प्राप्त करना संभव है?

जवाबों:


24

तुम कर सकते हो:

> echo XXXX | sed -e ':loop' -e 's/XX/XoX/g' -e 't loop'
XoXoXoX

साथ में:

  • -e ':loop' : "लूप" लेबल बनाएं
  • -e 't loop' : यदि पिछले प्रतिस्थापन सफल रहा तो "लूप" लेबल पर जाएं

10

इस विशेष मामले में लुक-फॉरवर्ड या लुक-बैक उपयोगी होगा। मुझे लगता है कि GNU sedइनका समर्थन नहीं करता है। के साथ perl:

perl -ne 's/X(?=X)/Xo/g; print;'

तुम भी देखो और देखो की तरह उपयोग कर सकते हैं:

s/(?<=X)(?=X)/o/g

कहाँ पे:

(?<=X)एक सकारात्मक खोज है, एक शून्य-लंबाई का अभिकथन जो यह सुनिश्चित करता है कि वर्तमान स्थिति
(?=X)से पहले हमारे पास एक X है, एक सकारात्मक रूप-रेखा है, एक शून्य-लंबाई का अभिकथन जो यह सुनिश्चित करता है कि हमारे पास वर्तमान स्थिति के बाद एक X है।

एक पर्ल वन-लाइनर का उपयोग करना:

perl -pe 's/(?<=X)(?=X)/o/g' inputfile

कहाँ पे:

-p Perl वर्तमान लाइन के एक अंतर्निहित प्रिंट के साथ कार्यक्रम के चारों ओर एक लूप मानने का कारण बनता है


5

लूपिंग जवाब वह सामान्य तरीका है जो आप पूछ रहे हैं।

हालांकि आपके डेटा के मामले में, आप यह सोचकर कि आप GNU का उपयोग कर रहे हैं:

sed 's/\B/o/g'

\bऔर \Bविकल्प हैं regex एक्सटेंशन :

  • \b शब्द सीमाएं, अर्थात "शब्द" वर्ण से "गैर-शब्द" वर्ण, या इसके विपरीत परिवर्तन
  • \Bके विपरीत मेल खाता है \b। यानी अंतराल "अंदर" शब्द। यह हमें एक शब्द के अंदर वर्णों को सम्मिलित करने की अनुमति देता है, लेकिन आवश्यकता के अनुसार बाहर नहीं।

इसे ऑनलाइन आज़माएं

यह मानता है कि इनपुट वर्ण वास्तव में सभी "शब्द" अक्षर हैं।


वैकल्पिक रूप से यदि आपके पास GNU sed नहीं है, या यदि इनपुट वर्ण सभी "शब्द" वर्ण नहीं हैं, तो भी आप लूप के माध्यम से अपना लक्ष्य प्राप्त कर सकते हैं:

sed 's/./&o/g;s/o$//'

यह बस oहर चरित्र के बाद रखता है और फिर oस्ट्रिंग से फाइनल निकालता है ।

इसे ऑनलाइन आज़माएं


1
यह मानता है कि इनपुट स्ट्रिंग में कुछ संख्या Xऔर कुछ नहीं है। यदि अन्य वर्ण मौजूद हैं तो दोनों समाधान विफल हो जाते हैं ...
AnoE

@AnoE दूसरे नमूने में, इसके Xद्वारा एक साधारण प्रतिस्थापन के साथ तय किया गया है .। कृपया देखें संपादित करें।
डिजिटल ट्रॉमा

ओपी द्वारा दिए गए मामले के बराबर नहीं। उन्होंने सटीक आरईएस दिए जिनकी उन्हें जरूरत है (एक स्ट्रिंग में XX की घटनाएँ बदलें)। आपके संस्करण केवल वही परिणाम देते हैं जो उनके द्वारा दिए गए सटीक इनपुट स्ट्रिंग्स के लिए हैं; जेनेरिक इनपुट स्ट्रिंग्स के लिए नहीं।
आओ

4

मैंने जाँच की कि क्या ऐसा करने के लिए किसी प्रकार का झंडा है।
यहां तक ​​कि अगर वह व्यवहार वहाँ था, तो यह अत्यधिक संसाधन खपत होने वाला है।

हालांकि, इस विशेष उपयोग के मामले में, अभिव्यक्ति को सिर्फ दो बार करना और आवश्यक कार्यक्षमता प्राप्त करना संभव है। 2 दोहराए जाने वाले sedभावों के साथ।

echo XX | sed -e 's/XX/XoX/g' -e 's/XX/XoX/g'     # outputs XoX
echo XXX | sed -e 's/XX/XoX/g' -e 's/XX/XoX/g'    # outputs XoXoX
echo XXXX | sed -e 's/XX/XoX/g' -e 's/XX/XoX/g'   # outputs XoXoXoX
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.