2012-04-11 15 views
16

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

यह कुछ डेटा एकत्र करता है, जो सामान की कई पंक्तियों को समाप्त करता है। $DATA में संग्रहीत उदाहरण के लिए।

अब, कुछ stfw के बाद मुझे sed -ei "s/_data_/${DATA}/g" mail.tpl और sed replace with variable with multiple lines जैसी कुछ चीज़ें मिलीं। उनमें से कोई भी काम नहीं करता है।

अब सवाल यह है कि, मुझे टेक्स्ट की कई पंक्तियों के साथ कुछ बदलने के लिए sed कैसे प्राप्त किया जा सकता है?

(sed करने के लिए विकल्प का भी स्वागत है!)

+1

संभव डुप्लिकेट (http://stackoverflow.com/questions/6684487/sed-replace-with-variable-with-multiple-lines) –

+1

@ZsoltBotykai आप नहीं कहते? : डी मैंने अपने प्रश्न में भी इसका उल्लेख किया ... –

उत्तर

10

आप "\n" एस के साथ अपने बहु पंक्ति पाठ का निर्माण करते हैं, तो इस रूप में एक सरल sed आदेश के साथ काम करेंगे:

DATA=`echo ${DATA} | tr '\n' "\\n"` 
#now, DATA="line1\nline2\nline3" 
sed "s/_data_/${DATA}/" mail.tpl 
+0

मुझे' sed: -e अभिव्यक्ति # 1, char 32: unterminated's 'कमांड मिल रहा है उस विधि से। –

+1

ओह, आपका संपादन नहीं देखा। यह वास्तव में काम करता है! –

+1

यह पूरी तरह पोर्टेबल नहीं है; सभी 'sed' dialects एक शाब्दिक न्यूलाइन का प्रतिनिधित्व करने के लिए '\ n' digraph स्वीकार नहीं करते हैं। कुछ अन्य बोलीभाषाओं में, आपको शायद एक शाब्दिक न्यूलाइन से पहले बैकस्लैश का उपयोग करने की आवश्यकता होगी। इस पृष्ठ पर अन्य उत्तरों आपको दिखाते हैं कि इसे और अधिक विस्तार से कैसे करें। – tripleee

8

awk?

kent$ cat test 
foo 
bar 
blah _data_and_data_ 
foo 
_data_ foobar _data_ again 


kent$ echo $DATA 
1 
2 
3 
4 
5 

kent$ awk -v r=$DATA '{gsub(/_data_/,r)}1' test 
foo 
bar 
blah 1 
2 
3 
4 
5and1 
2 
3 
4 
5 
foo 
1 
2 
3 
4 
5 foobar 1 
2 
3 
4 
5 again 
+1

हे भगवान, यह काम करता है! काश मैं आपको कई बार +1 कर सकता हूं, आपने मुझे आदमी बचाया! –

+2

अरे केंट, यह एक पुराना है, लेकिन आपको $ DATA के आसपास उद्धरण याद आ रहे हैं। की पुष्टि करें? –

+0

वास्तव में उद्धरण जोड़ना चाहिए: awk -vr = "$ डेटा" {gsub (/ _ डेटा _ /, आर)} 1 'परीक्षण –

7

मैं इसे करने की कोशिश की और sed 's/pattern/\na\nb\nc/g' लेकिन यह सब सिस्टम पर काम नहीं करता है । क्या काम करता है एक \ की जगह पैटर्न में एक नई पंक्ति के बाद, इस तरह डाल है:

sed 's/pattern/a\ 
b\ 
c/g' 

यह b और c युक्त जब पैटर्न में देखा जाता है एक लाइन से युक्त एक रेखा भी संलग्न।

export DATA="\\ 
a\\ 
b\\ 
c" 

और उसके बाद:

sed "s/pattern/${DATA}/g" 

नोट डबल कोट्स

एक चर में कहें

, डबल बैकस्लैश।

0

तुम एक अस्थायी फ़ाइल में अपने डेटा डाल दिया और चला सकते हैं:

$ sed '/_data_/r DATA_FILE' mail.tpl | sed '/_data_/d'> temp; mv temp mail.tpl 
+0

यह सबसे अच्छा काम है। – tripleee

7

मैं सुझाव है कि बस पर्ल के साथ sed जगह हैं इस तरह के आदेश:

perl -i.bak -pe 's/_data_/'"${DATA}"'/g' mail.tpl 
+1

यह केवल यही है जो ओएसएक्स पर मेरे लिए काम करता है। अन्य सभी sed और awk आधारित अनुमोदन मेरे लिए विफल रहा। –

5

अंगूठी वाहक के जवाब के लिए काम नहीं किया मुझे; मुझे लगता है कि tr का उपयोग गलत है, और जिस तरह से लिखा गया है, यह echo के उपयोग से नईलाइनों को आसानी से हटा देता है।

इसके बजाय, मैंने sed का उपयोग किया। मैंने न्यूलाइन (क्रेडिट: ज़्सॉल्ट बोटेकाई) को बदलने के लिए another answer से कोड का उपयोग किया। मुझे अपने इनपुट में कुछ डॉलर के संकेत ($) की भी उम्मीद थी, इसलिए मैंने इसका भी ख्याल रखा। आपको अन्य इनपुट हैंडलिंग जोड़ने की आवश्यकता हो सकती है। न्यूलाइन को संरक्षित करने के लिए echo में डबल कोट्स के उपयोग पर ध्यान दें।

DATA="$(cat whatever)" 
ESCAPED_DATA="$(echo "${DATA}" | sed ':a;N;$!ba;s/\n/\\n/g' | sed 's/\$/\\$/g')" 

तो फिर तुम sed में ${ESCAPED_DATA} उपयोग कर सकते हैं:

cat input | sed 's/one liner/'"${ESCAPED_DATA}"'/' > output 

बस सोचा था कि मैं हिस्सा था।

+0

यह अच्छी तरह से काम करता है जब 'bash' स्क्रिप्ट के साथ 'bash' स्क्रिप्ट में बहु-रेखा स्ट्रिंग्स का निर्माण किया गया है (शुरुआत में' बिल्ली 'निश्चित रूप से आवश्यक है, तब स्ट्रिंग पहले से ही नहीं है एक परिवर्तनीय)। – Ville

1

अस्थायी पाठ फ़ाइल में इको चर। mail.tpl में

सम्मिलित पाठ फ़ाइल और हटाने के डेटा mail.tpl से

echo ${DATA} > temp.txt  
sed -i -e "/_data_/r temp.txt" -e "//d" mail.tpl 
0

में सुनिश्चित नहीं हैं हिस्सा

sed 's/[pattern]/\ 
[line 1]\n\ 
[line 2]\n\ 
[line n]\n\ 
/g' mail.tpl 

में की जगह डाल करने के लिए "\ n" की कोशिश की है पहली पंक्ति में पठनीयता कारणों के लिए/\ है। उसके बाद प्रत्येक पंक्ति एक स्टैंड-अलोन लाइन है जैसे आप टेक्स्ट एडिटर में पाएंगे। पिछली पंक्ति स्टैंड-अलोन है, एक बार फिर पठनीयता के कारणों के लिए। यदि आवश्यक हो तो आप यह सब एक लाइन बना सकते हैं। जब मैंने इसका परीक्षण किया तो डेबियन जेसी पर काम करता है।

0

\ (अंतिम को छोड़कर) के साथ सभी नई लाइनों से बचने के लिए मेरे लिए काम किया। s कमांड को तोड़ने के लिए अंतिम नई लाइन से बच नहीं होना चाहिए।

उदाहरण:

DATA="a 
b 
c" 

ESCAPED=$(echo "${DATA}" | sed '[email protected][email protected]\\@g') 
echo "${ESCAPED}" 
a\ 
b\ 
c 

sed "s/pattern/${ESCAPED}/" file 
की [एसईडी कई पंक्तियों के साथ चर के साथ बदलें]
संबंधित मुद्दे