2012-04-11 82 views
16

我正在編寫一個bash腳本,它必須準備發送給用戶的電子郵件。使用sed用多行替換單詞?

它彙總了一些數據,最終形成多行東西。對於存儲在$DATA中的示例。

現在,在一些stfw後,我發現了一些東西,如sed -ei "s/_data_/${DATA}/g" mail.tplsed replace with variable with multiple lines。他們都沒有工作。

現在的問題是,我如何獲得sed來替換多行文本?

(替代sed也歡迎!)

+1

可能重複(http://stackoverflow.com/questions/6684487/sed-replace-with-variable-with-multiple-lines ) – 2012-04-11 14:06:11

+1

@ZsoltBotykai你不說? :D我甚至在我的問題中提到過...... – 2012-04-11 14:07:43

回答

10

如果建立與「\n」是你多行文本,這將用一個簡單的sed命令工作:

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

我得到了'sed:-e表達式#1,字符32:未終止的'命令'從那個方法。 – 2012-04-11 14:20:24

+1

糟糕,沒有看到您的編輯。這實際上有效! – 2012-04-11 14:34:01

+1

這不是完全可移植的;不是所有的'sed'方言都接受'\ n'圖來表示一個新的換行符。在其他一些方言中,您可能需要在文字換行符之前使用反斜槓。本頁面上的其他答案向您展示瞭如何更詳細地做到這一點。 – tripleee 2017-07-06 04:11:35

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次,你救了我男人! – 2013-12-21 00:11:49

+2

嘿肯特,這是一箇舊的,但你似乎缺少$ DATA的報價。確認? – 2014-02-13 01:53:41

+0

確實應該加上引號:awk -vr =「$ DATA」'{gsub(/ _ data _ /,r)}'test – 2017-09-06 18:39:32

7

我嘗試過了,sed 's/pattern/\na\nb\nc/g'但它不會在所有的系統工作。什麼工作是把一個\跟着一個換行符的替代模式,就像這樣:

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

這種含追加和bc圖案時,看到一個線路的線路。

爲了把它放在一個變量,使用雙反斜線:

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 2015-02-17 08:53:02

7

我會建議簡單地更換sed的Perl的命令是這樣的:

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

這是唯一在OSX上爲我工作的。所有其他基於sed和awk的批准都失敗了。 – 2017-12-01 13:45:03

5

環承載的回答並沒有爲工作我;我認爲tr的使用是錯誤的,它的寫法是通過使用echo來刪除換行符。我使用sed。我使用another answer的代碼替換換行符(信用:Zsolt Botykai)。我也預計在我的輸入中有一些美元符號($),所以我也照顧了。您可能需要添加其他輸入處理。請注意使用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

當''''''''''''''''''''構建多行字符串時,這種方法也可以很好地工作(當然,由於字符串已經在一個變量)。 – Ville 2017-07-30 21:43:04

1

回聲變量到臨時文本文件中。

插入文本文件導入mail.tpl和刪除數據從mail.tpl

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

不知道,如果你試圖把 「\ n」,在更換部分

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

出於可讀性原因,第一行有\ \。之後的每一行都是獨立的行,就像在文本編輯器中找到的一樣。由於可讀性的原因,最後一行是獨立的。如果需要,您可以製作所有這一行。當我測試它時,在Debian Jessie上工作。

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 
的[SED與多行可變取代]