2016-03-08 5 views
5

मेरे पास एक फ़ाइल है जिसमें कई रेखाएं हैं (रेखा डेलीमीटर ~ है)। प्रत्येक पंक्ति में, मेरे पास कई तत्व हैं जो एक delimiter '*' से अलग है। मैं क्या करना चाहता हूं, मेरे पास एक पंक्ति होगी जो मेरी फ़ाइल में स्ट्रिंग TRN के साथ शुरू होती है। इसमें 4 (टीआरएन सहित) या इसमें अधिक डेटा पॉइंट हो सकते हैं। कुछ की तरह,एक के साथ एक लाइन के एक हिस्से को कैसे बदल सकता है?

TRN*1*S521000035*1020494919~ 
TRN*1*S521000035*1020494919*787989800~ 

मैं abc123 को यह लाइनों से चौथे डेटा बिंदु बदलना चाहते हैं। यानी,

TRN*1*S521000035*abc123~ 
TRN*1*S521000035*abc123*787989800~ 

मैं नियमित अभिव्यक्ति

sed -i 's/^TRN\*(.*)\*(.*)\*(.*)$/abc123/g' file.txt 

लेकिन पूरी स्ट्रिंग abc123 के लिए प्रतिस्थापित किया जा रहा है के साथ एसईडी आदेश का उपयोग करने की कोशिश की।

क्या सीड कमांड का उपयोग करके केवल 4 वें डाटापॉइंट को बदलना संभव है?

उत्तर

2

जीएनयू का उपयोग पर अधिक जानकारी के संबंध के लिए आदमी पृष्ठों को पढ़ने के लिए चाहते हो सकता है sed:

$ sed -r -i 's/^((\w+\*){3})\w*(.*)/\1abc123\3/g' file.txt 

आउटपुट:

TRN*1*S521000035*abc123~ 
TRN*1*S521000035*abc123*787989800~ 
+0

काम किया। आपका बहुत बहुत धन्यवाद! –

+0

उपरोक्त मामले में मैं चौथे डेटा बिंदु को प्रतिस्थापित करना चाहता था, केवल तभी जब पहला डेटा बिंदु TRN है। इसलिए मैंने आपके आदेश को 'sed -r -i'/^ (TRN \ *) ((\ w + \ *) {2}) \ w * (के रूप में tweaked किया।*)/\ 1 \ 2abc123 \ 4/g '' –

2

sed आपका मित्र है।

इस परीक्षण किया संस्करण के लिए आजमाएँ:

$ sed "s/^\(TRN[*][^*][^*]*[*][^*][^*]*[*]\)[^*][^*]*\(.*~\)/\1abc123\2/" afile.txt 
TRN*1*S521000035*abc123~ 
TRN*1*S521000035*abc123*787989800~ 

आप regexp और sed

0

एडब्ल्यूके को एक सुंदर संक्षिप्त और पठनीय तरीके से चाल करना चाहिए। एफएस फ़ील्ड सेपरेटर को बदलता है ताकि आप यह पहचान सकें कि आप इसे लाइन के अंदर तोड़ना चाहते हैं।

$ awk 'BEGIN { FS="*|~" }{ sub($4, "abc123"); print $0}' file.txt 

TRN*1*S521000035*abc123~ 
TRN*1*S521000035*abc123*787989800~ 
+0

आप' 4 4 = "abc123" 'का उपयोग क्यों नहीं करते? इसके बजाय एक उप करना थोड़ा अजीब है। –

+0

क्योंकि जब मैंने ऐसा किया था तो उसने फ़ील्ड के बीच से "*" और पहली पंक्ति के अंत से "~" को हटा दिया था। यकीन नहीं है कि ऐसा क्यों किया, लेकिन उप समस्या हल हो गई। –

+0

क्योंकि आपने आउटपुट फ़ील्ड सेपरेटर ओएफएस सेट नहीं किया है। –

0

आप के साथ ऐसा कर सकते हैं sed यह बहुत आसान है awk साथ वांछित प्रभाव प्राप्त करने के लिए। कार्यक्रम awk का विश्लेषण करने और बदलने सारणीबद्ध संरचित डेटा, आपके मामले में के रूप में करने के लिए विशेष रूप से उपयोगी है:

awk -F'*' -v OFS='*' '{$4 = "abc123"; print}' 

यह पढ़ता है:

awk   Run the program awk 
-F'*'  Use the * as a field delimiter on input 
-v OFS='*' Use the * as a field delimiter on output 
'{   On each record … 
    $4 = "abc123"; 
      … set the 4th field to "abc123" 
    print 
      … and print the curent record 
    }' 

यह भी है कि उदाहरण पर विस्तार करने के लिए आसान है चुनिंदा अन्य क्षेत्रों के मूल्य के आधार पर, 4-वें क्षेत्र को प्रतिस्थापित करें।

+1

आपका 'awk' कमांड उदाहरण में पंक्ति 1 के अंत में '~' को हटा रहा है और वह व्यवहार नहीं चाहता है। – user3439894

+0

'awk' BEGIN {ORS = RS = "~ \ n"; एफएस = OFS = "*"} $ 4 = "abc123" ' – 123

+1

@ 123, आपकी टिप्पणी' awk' कमांड प्रत्येक मौजूदा पंक्ति के बाद एक अवांछित न्यूलाइन पेश करती है और '*** abc123 ~' की एक कचरा अंतिम पंक्ति। – user3439894

1

यह आपके लिए (जीएनयू sed) काम कर सकते हैं:

sed 's/[^*~]\+/abc123/4' file 

कुछ की चौथी घटना है जो एक ~ या एक *abc123 साथ शामिल नहीं है बदलें।

संबंधित मुद्दे