Bash忍者的问题:我有一个XML模板文件,其中包含{{VARIABLE_NAME}}
形式的一些模板标记,并希望用文本文件的内容查找/替换该标记的所有出现。
所以想象template.xml
看起来像这样:
<?xml>
<root>
<description>
{{DESCRIPTION}}
</description>
</root>
我有一个名为description.txt
的文本文件可能包含任何字符(为简单起见,我们假设它已经是xml安全的)。我想用标记的内容替换标记,支持换行符和其他字符。
以前我一直在我的代码中这样做(这对于简单的字符串非常有用):
sed -i '' -e "s/{{DESCRIPTION}}/$DESCRIPTION/g" template.xml
但是,如果$DESCRIPTION
包含换行符,则为sed balks:
sed: 1: "s/{{DESCRIPTION}}/Hello w ...": unescaped newline inside substitute pattern
是否有更好的方法可以执行此操作,或者我应首先使用$DESCRIPTION
变量中的转义变体搜索/替换所有换行符。还有其他任何我需要逃脱的角色,比如/
?
答案 0 :(得分:2)
这是一个用于替换的BASH(实际上是)脚本:
#!/bin/sh
while IFS= read -r line
do
case "$line" in
*{{DESCRIPTION}})
cat "description.txt"
;;
*)
echo "$line"
;;
esac
done <"template.xml"
在问题陈述中,“{{DESCRIPTION}}”单独出现在一行上。如果情况并非如此,则需要进行一些小的更改以保留该行上的其他数据。
答案 1 :(得分:1)
使用awk:
awk -v RS='\0' 'NR==FNR{r=$0;next}{sub(/\{\{DESCRIPTION\}\}/,r)}7' desc temp.xml
我想您知道如何使用重定向将输出保存到文件中。
test:在示例中,文件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>
答案 2 :(得分:1)
感谢您的回答。总是有兴趣学习在Bash中做事的新方法。我最后以不同的方式解决了它,但是,通过使用Bash的内置替换符号来转义字符串,我刚刚发现(sed
因为我仍然不太清楚而导致失败):< / p>
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命令接受替换字符串而没有抱怨,它会完美呈现输出文件。