Astrid
Astrid

Reputation: 1312

Escape UNIX character

This should be easy but i just can't get out of it:

I need to replace a piece of text in a .php file using the unix command-line.

using: sudo sed -i '' 's/STRING/REPLACEMENT/g' /file.php (The quotes after -i are needed because it runs on Mac Os X)

The string: ['password'] = ""; needs to be replaced by: ['password'] = "$PASS"; $PASS is a variable, so it gets filled in.

I got up to something like:

sudo sed -i '' 's/[\'password\'] = ""\;/[\'password\'] = "$PASS"\;/g' /file.php

But as i'm new with UNIX i don't know what to escape...

What should be changed? Thanks!

Upvotes: 0

Views: 872

Answers (2)

Ed Morton
Ed Morton

Reputation: 203985

Unfortunately sed cannot robustly handle variables that might contain various characters that are "special" to sed and shell. You need to use awk for this, e.g. with GNU awk for gensub():

gawk -v pass="$PASS" '{$0=gensub(/(\[\047password\047] = \")/,"\\1"pass,"g")}1' file

See how sed fails below when PASS contains a forward slash but awk doesn't care:

$ cat file
The string: ['password'] = ""; needs to be replaced

$ PASS='foo'
$ awk -v pass="$PASS" '{$0=gensub(/(\[\047password\047] = \")/,"\\1"pass,"g")}1' file
The string: ['password'] = "foo"; needs to be replaced
$ sed "s/\(\['password'\] = \"\)\(\";\)/\1$PASS\2/g" file
The string: ['password'] = "foo"; needs to be replaced

$ PASS='foo/bar'
$ awk -v pass="$PASS" '{$0=gensub(/(\[\047password\047] = \")/,"\\1"pass,"g")}1' file
The string: ['password'] = "foo/bar"; needs to be replaced
$ sed "s/\(\['password'\] = \"\)\(\";\)/\1$PASS\2/g" file
sed: -e expression #1, char 38: unknown option to `s'

You need to use \047 or some other method (e.g. '"'"' if you prefer) to represent a single quote within an awk script that's single-quote-delimitted.

In awks without gensub() you just use gsub() instead:

awk -v pass="$PASS" '{pre="\\[\047password\047] = \""; gsub(pre,pre pass)}1' file

Upvotes: 1

Kent
Kent

Reputation: 195169

if you want to expand variable in sed, you have to use double quote, so something like

sed -i... "s/.../.../g" file

that is, you don't have to escape those single quotes, also you could use group reference to save some typing. you could try:

sudo sed -i '' "s/\(\['password'\] = \"\)\(\";\)/\1$PASS\2/g" /file.php

Upvotes: 0

Related Questions