sed/

2012-04-25 13 views
21

युक्त तारों को खोज और प्रतिस्थापित करें मुझे sed का उपयोग करने के लिए वर्ण वाली टेक्स्ट को /etc/myconfig में स्ट्रिंग्स को खोजने और बदलने के लिए समस्या का पता लग रहा है।sed/

उदाहरण के लिए, अपने मौजूदा पाठ फ़ाइल में, मेरे पास है:

myparam /path/to/a argB=/path/to/B xo 

और मैं इस के द्वारा बदल दिया हैं:

myparam /path/to/c argB=/path/to/D xo 

मैं पार्टी में ऐसा करने का प्रयास किया:

line='myparam /path/to/a argB=/path/to/B xo' 
line_new='myparam /path/to/c argB=/path/to/D xo' 
sed -i 's/$line/$line_new/g' /etc/myconfig 

लेकिन कुछ भी नहीं होता है।

का प्रयास

grep -rn "$line" /etc/myconfig 

मुझे 'myparam /path/to/a argB=/path/to/B xo' लौट हालांकि करता है।

इस खोज को निष्पादित करने के लिए मेरे sed कमांड को व्यक्त करने और / कमांड के साथ सही तरीके से निपटने का सही तरीका क्या है? (मुझे लगता है कि मेरी तार में / चरित्र वाले मुझे समस्या दे रहे हैं क्योंकि मैं खोज और कोई समस्या नहीं के साथ पाठ फ़ाइल में एक और लाइन को बदलने के लिए एक समान sed आदेश का इस्तेमाल किया और उस पंक्ति एक / चरित्र नहीं है लगता है।

+1

प्रतिस्थापन और उद्धरण नियम वास्तव में विशेष रूप से sed की बजाय बाश के बारे में हैं। आप एक टैग के रूप में bash जोड़ना चाह सकते हैं। – KarlM

+0

ठीक है। टैग के रूप में 'bash' जोड़ देगा। –

उत्तर

32

बैकस्लैश से बचने मत करो; तुम अपने आप को भ्रमित करेंगे s आदेश है कि पाठ में प्रकट नहीं होता (मैं नीचे दिए गए उदाहरण में % उपयोग कर रहा हूँ) के बाद एक अलग प्रतीक का उपयोग करें:

line_old='myparam /path/to/a argB=/path/to/B xo' 
line_new='myparam /path/to/c argB=/path/to/D xo' 
sed -i "s%$line_old%$line_new%g" /etc/myconfig 

इसके अलावा। , डबल स्ट्रोट्स में पूरी स्ट्रिंग संलग्न करें; सिंगल कोट्स का उपयोग करने का अर्थ है कि sedदेखता है विस्तृत मूल्य के बजाय(मूल में)। एकल उद्धरण के अंदर, कोई विस्तार नहीं है और कोई मेटाएक्टेक्टर नहीं हैं। यदि आपके पाठ में लगभग कोई सादा पाठ वर्ण हो सकता है, तो डिलीमीटर के रूप में नियंत्रण वर्ण (उदा। नियंत्रण-ए या नियंत्रण-जी) का उपयोग करें।

ध्यान दें कि -i का उपयोग यहां दर्पणों में दर्पण है, लेकिन यह जीएनयू sed के उपयोग को मानता है। बीएसडी sed (मैक ओएस एक्स पर भी पाया गया) एक प्रत्यय की आवश्यकता है। आप सीटू में बदलने के लिए sed -i '' … का उपयोग कर सकते हैं; यह जीएनयू sed के साथ काम नहीं करता है। दोनों के बीच पोर्टेबल होने के लिए, -i.bak का उपयोग करें; जो दोनों के साथ काम करेगा - लेकिन आपको एक बैकअप फ़ाइल देता है जिसे आप शायद हटाना चाहते हैं। अन्य यूनिक्स प्लेटफ़ॉर्म (उदा। एईक्स, एचपी-यूएक्स, सोलारिस) में sed के वेरिएंट हो सकते हैं जो -i का समर्थन नहीं करते हैं। sed के लिए POSIX विनिर्देशन की आवश्यकता नहीं है।

+0

धन्यवाद!डबल कोट '' 'और'% 'ने चाल की। ​​मैंने मूल रूप से'/'अक्षर से '/' वर्ण से बचने की कोशिश की और यह बिल्कुल काम नहीं किया। –

+0

ध्यान दें कि यदि आपको कई पंक्तियों को निर्दिष्ट करने की आवश्यकता है रेगेक्स और रेगेक्स द्वारा स्लेश होते हैं, आप 'sed -n' \ @ dir/file @, \ @ dir2/file2 @ p 'का उपयोग कर सकते हैं, जहां '@' से पहले बैकस्लैश इंगित करता है कि '@' खोज डिलीमीटर है यह अभिव्यक्ति –

+0

ध्यान दें कि किसी को 'sed -i -e' – PhysicalChemist

12

यह आप के लिए काम कर सकते हैं:

sed -i "s|$line|$line_new|g" /etc/myconfig 

आप " के उपयोग करना चाहिए ताकि $line और $new_line अंतर्वेशित कर रहे हैं। | या मिलान या प्रतिस्थापन तारों में किसी भी चरित्र को डिलीमीटर के रूप में उपयोग न करें।

+1

ठीक है। मुझे '|' चाल के बारे में पता नहीं था। तो आप कहने का मतलब है कि कोई भी delimiter तब तक काम करेगा जब तक यह खोज में खोज या तारों को प्रतिस्थापित नहीं करता है? –

+0

हां; 's' के बाद पहला अक्षर कमांड को दो हिस्सों में अलग करने के लिए प्रयोग किया जाता है; मिलान करने के लिए पैटर्न और प्रतिस्थापन पैटर्न। '/' तीन बार उपयोग/खोज/प्रतिस्थापित/' लेकिन 's | search | replace |' या 's% खोज%%' को भी बदलता है। पर्ल मिलान करने वाले ब्रैकेट ('s {search} {replace}') की अनुमति देता है लेकिन 'sed' नहीं करता है (जब तक, शायद, आपने पर्ल पैटर्न विकल्प को सक्रिय नहीं किया है यदि आपके पास GNU 'sed' है)। –

+1

हां, कारण के भीतर। '|' उपयोग करने के लिए एक आसान है क्योंकि यह फ़ाइल में दिखाई देने की संभावना नहीं है। हालांकि यह एक मेटाएक्टेक्टर (वैकल्पिकता में उपयोग किया जाता है) है, इसलिए यदि आप कहना चाहते हैं कि यह/यह \/वह/उन/'तो' ''' या '#' या ',' या '?' या ' % 'इत्यादि। यह भी ध्यान दें कि एक वैकल्पिक डिलीमीटर का उपयोग करने के लिए खोज कमांड '/.../' के लिए प्रतिस्थापन आदेश के लिए बैकस्लैश के साथ विकल्प को आगे बढ़ाएं। '\ | foo |' – potong