Rohit Kanade
Rohit Kanade

Reputation: 21

sed command not working properly on ubuntu

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.

Upvotes: 1

Views: 523

Answers (3)

Ed Morton
Ed Morton

Reputation: 203209

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.

Upvotes: 1

hek2mgl
hek2mgl

Reputation: 157947

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

Upvotes: 1

Andrew Kay
Andrew Kay

Reputation: 274

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

Upvotes: 1

Related Questions