我有一个名为`config_3_setConfigPW.ldif的文件?包含以下行:
{pass}
在终端上,我使用了以下命令
SLAPPASSWD=Pwd&0011
sed -i "s@{pass}@$SLAPPASSWD@" config_3_setConfigPW.ldif
它应将{pass}
替换为Pwd&0011
,但会生成Pwd{pass}0011
。
答案 0 :(得分:1)
原因是在sed看到它之前扩展了SLAPPASSWD shell变量。所以sed看到了:
sed -i "s@{pass}@Pwd&0011@" config_3_setConfigPW.ldif
当一个“&”在模式的右侧,它表示“复制匹配的输入”,在您的情况下匹配的输入是“{pass}”。
真正的问题是你必须逃避SLAPPASSWD中可能出现的所有特殊字符,以防止sed这样做。例如,如果密码中包含字符“@”,则sed会认为它是替换命令的结尾,并给出语法错误。
因此,我不会使用sed。你可以尝试gawk或perl吗?
例如,这将在awk中打印出已修改的文件(尽管它仍假定SLAPPASSWD不包含“character
awk -F \{pass\} ' { print $1"'${SLAPPASSWD}'"$2 } ' config_3_setConfigPW.ldif
答案 1 :(得分:1)
那是因为$SLAPPASSWD
包含字符序列&
,它是sed
使用的元字符,并评估s
命令中匹配的文本。含义:
sed 's/{pass}/match: &/' <<< '{pass}'
会给你:
match: {pass}
前一段时间我曾问过这个问题:"Is it possible to escape regex metacharacters reliably with sed"。这里的答案显示了如何在将密码用作替换部件之前可靠地转义密码:
pwd="Pwd&0011"
pwdEscaped="$(sed 's/[&/\]/\\&/g' <<< "$pwd")"
# Now you can safely pass $pwd to sed
sed -i "s/{pass}/$pwdEscaped/" config_3_setConfigPW.ldif
答案 2 :(得分:1)
请记住,sed NEVER对字符串进行操作。 sed搜索的东西是一个正则表达式,它替换它的东西是字符串式的,但有一些你需要注意的元字符,例如&
或\<number>
,所有这些都需要避免使用sed分隔符/
。
如果你想操作字符串,你需要使用awk:
awk -v old="{pass}" -v new="$SLAPPASSWD" 's=index($0,old){ $0 = substr($0,1,s-1) new substr($0,s+length(old))} 1' file
如果旧的或新的包含转义字符,即使上面也需要调整。