我们在脚本中使用sed命令将文件内容替换为变量中的值
例如..
export value="dba01upc\Fusion_test"
sed -i "s%{"sara_ftp_username"}%$value%g" /home_ldap/user1/placeholder/Sara.xmlsed命令将忽略诸如'\‘之类的特殊字符,并替换为不带'\’的字符串"dba01upcFusion_test“。如果我像export value='dba01upc\Fusion_test‘(使用'\’括在‘’中)进行导出,则该命令有效。但不幸的是,我们的客户想要导出带有单/双引号的原始文本dba01upc\Fusion_test,并且他不想在文本中添加任何额外的字符。有没有人可以告诉我怎么让sed来放置带有特殊字符的文本..
更换前: Sara.xml
<?xml version="1.0" encoding="UTF-8"?>
<ser:service-account >
<ser:description/>
<ser:static-account>
<con:username>{sara_ftp_username}</con:username>
</ser:static-account>
</ser:service-account>更换后: Sara.xml
<?xml version="1.0" encoding="UTF-8"?>
<ser:service-account>
<ser:description/>
<ser:static-account>
<con:username>dba01upcFusion_test</con:username>
</ser:static-account>
</ser:service-account>提前感谢
发布于 2014-07-23 05:52:55
使用sed不能很好地解决这个问题。只需使用awk即可:
awk -v old="string1" -v new="string2" '
idx = index($0,old) {
$0 = substr($0,1,idx-1) new substr($0,idx+length(old))
}
1' file啊,@mklement0有一个很好的观点--为了防止转义被解释,你需要传入arg列表中的值和文件名,然后从文件名中赋值,而不是用-v赋值给变量(参见我很久以前在http://cfajohnson.com/shell/cus-faq-2.html#Q24上为comp.unix.shell常见问题解答写的摘要,但显然忘记了!)。
以下代码将在每行找到的每个搜索字符串上进行所需的替换(a\ta -> e\tf):
$ cat tst.awk
BEGIN {
old=ARGV[1]; delete ARGV[1]
new=ARGV[2]; delete ARGV[2]
lgthOld = length(old)
}
{
head = ""; tail = $0
while ( idx = index(tail,old) ) {
head = head substr(tail,1,idx-1) new
tail = substr(tail,idx+lgthOld)
}
print head tail
}
$ cat file
a\ta a a a\ta
$ awk -f tst.awk 'a\ta' 'e\tf' file
e\tf a a e\tffile中的空格是制表符。如果您愿意,您可以将ARGV3向下移动并调整ARGC,但在大多数情况下这并不是必需的。
发布于 2014-07-23 23:13:33
利用后见之明更新,以呈现options
bash 解决方案,并且您的输入文件很小并且保留多个尾随换行符并不重要,请参阅您想要一个Python完整的第三方模板解决方案<代码>E242,例如,考虑j2cli,Jinja2的模板-如果您有Python和pip,使用sudo pip install j2cli安装。简单示例(请注意,由于替换字符串是通过文件提供的,因此这可能不适用于敏感数据;请注意双花括号({{...}})):
dba01upc\Fusion_test =‘dba01upc\Fusion_test’echo "sara_ftp_username=$value“>data.env echo >data.env >tmpl.xml j2 tmpl.xml data.env # -> Dba01upc
如果您使用sed**,,则需要仔细转义搜索和替换字符串**,因为:
sed不支持使用文字字符串作为替换字符串-它总是解释替换字符串中的特殊字符/序列。必须以不会将其字符误认为特殊正则表达式字符的方式对搜索字符串文字进行转义。下面使用两个通用助手函数来执行此转义(引用),这两个函数应用了"Is it possible to escape regex characters reliably with sed?"中介绍的技术
#!/usr/bin/env bash
# SYNOPSIS
# quoteRe <text>
# DESCRIPTION
# Quotes (escapes) the specified literal text for use in a regular expression,
# whether basic or extended - should work with all common flavors.
quoteRe() { sed -e 's/[^^]/[&]/g; s/\^/\\^/g; $!a\'$'\n''\\n' <<<"$1" | tr -d '\n'; }
# '
# SYNOPSIS
# quoteSubst <text>
# DESCRIPTION
# Quotes (escapes) the specified literal string for safe use as the substitution string (the 'new' in `s/old/new/`).
quoteSubst() {
IFS= read -d '' -r < <(sed -e ':a' -e '$!{N;ba' -e '}' -e 's/[&/\]/\\&/g; s/\n/\\&/g' <<<"$1")
printf %s "${REPLY%$'\n'}"
}
# The search string.
search='{sara_ftp_username}'
# The replacement string; a demo value with characters that need escaping.
value='&\1%"'\'';<>/|dba01upc\Fusion_test'
# Use the appropriately escaped versions of both strings.
sed "s/$(quoteRe "$search")/$(quoteSubst "$value")/g" <<<'<el>{sara_ftp_username}</el>'
# -> <el>&\1%"';<>/|dba01upc\Fusion_test</el>quoteRe()和quoteSubst() 都能正确处理多行字符串。但是,sed在缺省情况下一次只读取一行,因此只有在显式读取once.中的多行(或所有行)的sed命令中,才能将quoteRe()与多行字符串一起使用
与命令替换(**$(...)**),一起使用时,
quoteRe()始终是安全的,因为它始终返回单行字符串(输入中的换行符编码为'\n').$(...),,如果使用quoteSubst()时字符串的末尾换行符为,则不能使用换行符因为后者将删除最后一个尾随的换行符,从而破坏编码(因为quoteSubst() \-escapes实际换行符,所以返回的字符串将以悬空的\结尾)。因此,对于带有尾随换行符的command.字符串,请先使用IFS= read -d '' -r escapedValue < <(quoteSubst "$value")将转义值读取到一个单独的变量中,然后在
中使用该变量
发布于 2014-07-24 01:59:45
这可以通过单独使用bash内建来完成--没有sed、没有awk等等。
orig='{sara_ftp_username}' # put the original value into a variable
new='dba01upc\Fusion_test' # ...no need to 'export'!
contents=$(<Sara.xml) # read the file's content into
new_contents=${contents//"$orig"/$new} # use parameter expansion to replace
printf '%s' "$new_contents" >Sara.xml # write new content to disk有关使用参数扩展进行字符串替换的信息,请参阅the relevant part of BashFAQ #100。
https://stackoverflow.com/questions/24890230
复制相似问题