1

I have one file named `config_3_setConfigPW.ldif? containing the following line:

{pass}

on terminal, I used following commands

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

It should replace {pass} to Pwd&0011 but it generates Pwd{pass}0011.

3 Answers 3

1

The reason is that the SLAPPASSWD shell variable is expanded before sed sees it. So sed sees:

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

When an "&" is on the right hand side of a pattern it means "copy the matched input", and in your case the matched input is "{pass}".

The real problem is that you would have to escape all the special characters that might arise in SLAPPASSWD, to prevent sed doing this. For example, if you had character "@" in the password, sed would think it was the end of the substitute command, and give a syntax error.

Because of this, I wouldn't use sed for this. You could try gawk or perl?

eg, this will print out the modified file in awk (though it still assumes that SLAPPASSWD contains no " character

awk -F \{pass\} ' { print  $1"'${SLAPPASSWD}'"$2 } ' config_3_setConfigPW.ldif
Sign up to request clarification or add additional context in comments.

1 Comment

You're on the right track by using awk but you're using very error-prone syntax. The correct syntax for your suggested approach be awk -F '{pass}' -v new="$SLAPPASSWD" ' { print $1 new $2 } '.
1

That's because$SLAPPASSWD contains the character sequences & which is a metacharacter used by sed and evaluates to the matched text in the s command. Meaning:

sed 's/{pass}/match: &/' <<< '{pass}'

would give you:

match: {pass}

A time ago I've asked this question: "Is it possible to escape regex metacharacters reliably with sed". Answers there show how to reliably escape the password before using it as the replacement part:

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

Comments

1

Bear in mind that sed NEVER operates on strings. The thing sed searches for is a regexp and the thing it replaces it with is string-like but has some metacharacters you need to be aware of, e.g. & or \<number>, and all of it needs to avoid using the sed delimiters, / typically.

If you want to operate on strings you need to use 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

Even the above would need tweaked if old or new contained escape characters.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.