sed कब्जा समूह काम नहीं कर रहा है


27

मेरे पास प्रारूप की एक स्ट्रिंग है [0-9]+\.[0-9]+\.[0-9]। मुझे पहले, दूसरे और तीसरे नंबर को अलग-अलग निकालना होगा। जैसा कि मैं इसे समझता हूं, कैप्चर समूहों को इसके लिए सक्षम होना चाहिए। मैं sed "s/\([0-9]*\)/\1/gपहला नंबर sed "s/\([0-9]*\)/\2/gपाने के लिए, दूसरा नंबर sed "s/\([0-9]*\)/\3/gपाने के लिए और तीसरा नंबर पाने के लिए उपयोग करने में सक्षम होना चाहिए । प्रत्येक मामले में, हालांकि, मुझे पूरी स्ट्रिंग मिल रही है। ये क्यों हो रहा है?


6
कब्जा समूह पूरे समूह पर कब्जा ... समूह में व्यक्तिगत तत्व नहीं। आपको 's/\([0-9]\)\([0-9]\)\([0-9]\).*/\1\2\3/'व्यक्तिगत संख्याओं को कैप्चर करने के लिए कुछ चाहिए ।
मुनीर

जवाबों:


45

हम आपके इनपुट के उदाहरण के बिना आपको पूर्ण उत्तर नहीं दे सकते, लेकिन मैं आपको बता सकता हूं कि कैप्चर समूहों की आपकी समझ गलत है। आप उन्हें क्रमिक रूप से उपयोग नहीं करते हैं, वे केवल उसी प्रतिस्थापन ऑपरेटर के बायीं ओर रेगेक्स को संदर्भित करते हैं। यदि आप पकड़ते हैं, उदाहरण के लिए, /(foo)(bar)(baz)/तब fooहोगा \1, barहोगा \2और bazहोगा \3। आप ऐसा नहीं कर सकते s/(foo)/\1/; s/(bar)/\2/, क्योंकि, दूसरी s///कॉल में, केवल एक कैप्चर किया गया समूह है, इसलिए \2इसे परिभाषित नहीं किया जाएगा।

इसलिए, अंकों के अपने तीन समूहों को पकड़ने के लिए, आपको यह करना होगा:

sed 's/\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\)/\1 : \2 : \3/'

या, अधिक पठनीय:

sed -E 's/([0-9]*)\.([0-9]*)\.([0-9]*)/\1 : \2 : \3/'

1
पहले उदाहरण में कोष्ठकों से बचने का क्या लाभ है?
जोश एम।

3
@JoshM। आप पैटर्न पर कब्जा करने के लिए इस्तेमाल किया जा करने के लिए उन्हें भागने की जरूरत है। आम तौर /(foo)/पर सेड में एक शाब्दिक (वर्ण fooऔर उसके बाद एक शाब्दिक मिलान होगा )। यदि आप एक समूह पर कब्जा करना चाहते हैं, तो आपको या तो कोष्ठकों से बचने या -Eविकल्प का उपयोग करने की आवश्यकता है।
terdon

मैं लगभग हमेशा -rध्वज का उपयोग करता हूं इसलिए मुझे लगता है कि मैं अभी तक इसमें नहीं चला हूं।
जोश एम।

1
@JoshM। हाँ, -rध्वज भी ऐसा करेगा, लेकिन यह पोर्टेबल नहीं है। GNU sed इसका समर्थन करता है लेकिन कई अन्य नहीं करते हैं। -Eअधिक सार्वभौमिक है।
terdon

9

उदाहरण:

$ echo "123.456.78" |sed 's/\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\)/\1/'
123

$ echo "123.456.78" |sed 's/\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\)/\2/'
456

$ echo "123.456.78" |sed 's/\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\)/\3/'
78

या, सभी एक साथ:

$ echo "123.456.78" |sed 's/\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\)/\1 : \2 : \3/'
123 : 456 : 78

2

सभी बच गए कोष्ठक से बचने के लिए -r, --regexp- विस्तारित के साथ Sed का उपयोग करें।

echo "1234.567.89" | sed -r 's/([0-9]+)\.([0-9]+)\.([0-9]+)/\1, \2, \3/' 
1234, 567, 89    #output
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.