2010-11-30 16 views
14

sed मैनुअल स्पष्ट रूप से बताता है कि एक विकल्प में प्रतिस्थापन स्ट्रिंग के लिए उपलब्ध उपलब्ध बैकरेरेंस को \ 1 से \ 9 क्रमांकित किया गया है। मैं एक लॉग फ़ाइल को पार्स करने की कोशिश कर रहा हूं जिसमें 10 फ़ील्ड हैं।sed backvent sed backference सीमा 1 के माध्यम से 9

मेरे पास इसके लिए गठित रेगेक्स है लेकिन दसवां मैच (और बाद में कुछ भी) सुलभ नहीं है।

क्या किसी के पास केएसएच में इस सीमा को रोकने के लिए एक शानदार तरीका है (या कोई भी भाषा जो शायद मैं शेल स्क्रिप्टिंग के लिए बंद कर सकता हूं)?

+2

आप किसी भी स्क्रिप्टिंग भाषा का उपयोग कर सकते हैं जो आपको इसके लिए एक-लाइनर लिखने देता है। 'perl -pe '/ yourregexhere/$ 1 $ 2 $ 3 $ 4 $ 5 $ 6 $ 7 $ 8 $ 9 $ 10 /'' –

+0

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

+1

'awk' के लिए नौकरी की तरह लगता है - फ़ील्ड 10' $ 10' –

उत्तर

13

क्या आप perl -pe 's/(match)(str)/$2$1/g;' को उपयोगकर्ता के स्थान पर देख सकते हैं? बैकरेफर सीमा को बाधित करने का तरीका sed के अलावा कुछ और उपयोग करना है।

इसके अलावा, मुझे लगता है कि आप अपने प्रतिस्थापन को दो चरणों में कर सकते हैं, लेकिन मुझे आपका पैटर्न नहीं पता है, इसलिए मैं आपकी मदद कैसे नहीं कर सकता।

+0

धन्यवाद, यह बहुत अच्छा काम करता है। अब मुझे यह पता लगाने की जरूरत है कि फ्लाई पर पैटर्न कैसे उत्पन्न करें और इस कमांड को ksh स्क्रिप्ट से चलाएं, लेकिन यह एक और दिन के लिए एक सवाल है। –

3

आप एक शेल स्क्रिप्ट समाधान के लिए पूछ रहे हैं - इसका मतलब है कि आप केवल sed का उपयोग करने के लिए सीमित नहीं हैं, सही? अधिकांश गोले सरणी का समर्थन करते हैं, तो शायद आप लाइन को एक सर सरणी चर में पार्स कर सकते हैं? यदि आवश्यकता हो, तो आप प्रत्येक पास एक ही पंक्ति को कई बार पार्स कर सकते हैं, प्रत्येक पास पर जानकारी के विभिन्न बिट्स निकाल सकते हैं।

क्या ऐसा होगा?

1

ऐसे समाधान पर विचार करें जिसे नियमित अभिव्यक्ति बैक्रेरेंस के उपयोग की आवश्यकता नहीं है। उदाहरण के लिए, यदि आपके पास एक साधारण फ़ील्ड डिलीमीटर है, तो split का उपयोग करें, या यहां तक ​​कि perl के बजाय अपनी प्रसंस्करण के लिए भी अजीब का उपयोग करें।

3

स्ट्रीम के साथ-साथ विभाजित करें, जब तक प्रतिस्थापित तत्व उस समूह में हों, जिसे आप उन्हें विभाजित करते हैं। जब मैंने डेट स्प्लिट किया तो मैं डेट-टाइम को 14 अंकों की स्ट्रिंग में फिर से बदल सकता था, मुझे स्ट्रीम को 3 बार विभाजित करना पड़ा।

echo "created: 02/05/2013 16:14:49" | sed -e 's/^\([[:alpha:]]*: \)//' -e 's/\([0-9]\{2\}\)\(\/\)\([0-9]\{2\}\)\(\/\)\([0-9]\{4\}\)\(\)/\5\1\3/' -e 's/\([0-9]\{2\}\)\(\:\)\([0-9]\{2\}\)\(\:\)\([0-9]\{2\}\)/\1\3\5/' 
0

आप GNU awk है, तो आप नियंत्रण में भी बहुत कुछ कर सकते हैं। इसके लिए आपको match(source,/regex/,array) निर्माण की आवश्यकता होगी।

उदाहरण: परीक्षण के लिए

नमूना इनपुट:

echo "$x" 
p1=aaa,p2=bb,p3=cc,p4=dd,p5=ee,p6=ff,p7=gg,p8=hh,p9=ii,p10=jj 

sed ठीक काम करता है \9 तक:

echo $x |sed -r 's/p1=([^,]+).*p2=([^,]+).*p3=([^,]+).*p4=([^,]+).*p5=([^,]+).*p6=([^,]+).*p7=([^,]+).*p8=([^,]+).*p9=([^,]+)(.*)/\1 \2 \3 \4 \5 \6 \7 \8 \9/' 
aaa bb cc dd ee ff gg hh ii 

sed तोड़ दिया जब \10 जोड़ा जाता है, यह माना जाता है \1 + 0 है।

echo $x |sed -r 's/p1=([^,]+).*p2=([^,]+).*p3=([^,]+).*p4=([^,]+).*p5=([^,]+).*p6=([^,]+).*p7=([^,]+).*p8=([^,]+).*p9=([^,]+).*p10=([^,]+)(.*)/\1 \2 \3 \4 \5 \6 \7 \8 \9 \10/' 
aaa bb cc dd ee ff gg hh ii aaa0 

awk बचाव के लिए जब 9 से अधिक जोड़ा गया कोई भी संदर्भ संदर्भ जोड़ा गया है। यहां 10 वें रिफ्रेंस जोड़ा गया है:

echo "$x" |awk '{match($0,/p1=([^,]+).*p2=([^,]+).*p3=([^,]+).*p4=([^,]+).*p5=([^,]+).*p6=([^,]+).*p7=([^,]+).*p8=([^,]+).*p9=([^,]+).*p10=([^,]+)(.*)/,a);print a[1],a[2],a[3],a[4],a[5],a[6],a[7],a[8],a[9],a[10]}' 
aaa bb cc dd ee ff gg hh ii jj