sed命令在ubuntu上无法正常工作

时间:2016-01-14 11:21:55

标签: sed

我有一个名为`config_3_setConfigPW.ldif的文件?包含以下行:

{pass}

在终端上,我使用了以下命令

SLAPPASSWD=Pwd&0011   
sed -i "s@{pass}@$SLAPPASSWD@" config_3_setConfigPW.ldif

它应将{pass}替换为Pwd&0011,但会生成Pwd{pass}0011

3 个答案:

答案 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

如果旧的或新的包含转义字符,即使上面也需要调整。