2013-12-20 93 views
1

Bash ninjas問題:我有一個XML模板文件,其格式爲{{VARIABLE_NAME}},有一些模板標記並希望查找/替換該標記的所有出現位置文本文件的內容。Bash/sed字符串替換爲文件內容(包含換行符)

所以,想象template.xml看起來是這樣的:

<?xml> 
<root> 
    <description> 
     {{DESCRIPTION}} 
    </description> 
</root> 

而且我有一個名爲description.txt可能潛在地包含任何字符的文本文件(假設它已經是XML的安全爲簡單起見)。我想用文件內容替換標記,支持換行符和其他字符。

sed -i '' -e "s/{{DESCRIPTION}}/$DESCRIPTION/g" template.xml 

但是,如果$DESCRIPTION包含換行符,sed的梁木:

sed: 1: "s/{{DESCRIPTION}}/Hello w ...": unescaped newline inside substitute pattern 

此前我已經在我的代碼這樣的(這對於簡單的字符串的偉大工程)一直在做這個有更好的方法來做到這一點,或者我應該首先在$DESCRIPTION變量中首先搜索/替換所有帶有轉義變體的換行符。還有我需要逃脫的任何其他角色,如/

回答

0

感謝您的答案。始終有興趣學習在Bash做事情的新方法。最後我以不同的方式解決它,但是,通過轉義使用bash內置的替換符號的字符串,這是我剛發現(sed未能在這個原因我還是不很清楚):

DESCRIPTION=`cat description.txt` 
DESCRIPTION=${DESCRIPTION//$'\n'/\\$'\n'} # escape newlines 
DESCRIPTION=${DESCRIPTION//\//\\\/} # escape slashes 
DESCRIPTION=${INPUT//$'&'/\\$'&'amp;} # escape ampersands 
# other xml-escaping... 

...然後使用sed實際做的Output.xml更換直列:

cp -f template.xml output.xml 
sed -i '' -e "s/{{DESCRIPTION}}/$DESCRIPTION/g" output.xml 

由於換行,現在斜槓轉義(我失去了什麼?)sed命令接受替換字符串沒有抱怨,它完美地呈現輸出文件。

1

用awk:

awk -v RS='\0' 'NR==FNR{r=$0;next}{sub(/\{\{DESCRIPTION\}\}/,r)}7' desc temp.xml 

我想你知道如何使用重定向到輸出保存到一個文件播放。

測試:在本例中,文件f包含許多 「特殊」 的字符

kent$ cat f.xml 
<?xml> 
<root> 
    <description> 
     {{DESCRIPTION}} 
    </description> 
</root> 

kent$ cat f 
foo 
' 
" 
O"' 
/
\ 



     - 
bar 

kent$ awk -v RS='\0' 'NR==FNR{r=$0;next}{sub(/\{\{DESCRIPTION\}\}/,r)}7' f f.xml 
<?xml> 
<root> 
    <description> 
     foo 
' 
" 
O"' 
/
\ 



     - 
bar 

    </description> 
</root> 
+0

這幾乎可以正常工作,但由於某些原因,它只取文件的最後一行,忽略最後一行之前的任何內容。這可能是我的錯,我不知道awk。 – devios1

+0

@chaiguy是你的awk gnu嗎? – Kent

+0

我正在運行Mac OS X 10.9,因此可能不會。 – devios1

2

這裏有一個BASH(SH,實際上)腳本做替代:

#!/bin/sh 
while IFS= read -r line 
do 
    case "$line" in 
     *{{DESCRIPTION}}) 
      cat "description.txt" 
      ;; 
     *) 
      echo "$line" 
      ;; 
    esac 
done <"template.xml" 

中存在的問題聲明,「{{DESCRIPTION}}」單獨顯示在一行上。如果通常情況並非如此,則需要做一些小的改動來保存線上的其他數據。