SteveMc
SteveMc

Reputation: 65

Escape single quotes in sed

I have a string:

'driver' => 'Cake\Database\Driver\Mysql'

Which I need to replace with:

'foo' => 'bar'

But none of my sed commands seem to be quite right, e.g.

sed -i "s/\x27driver\x27 => \x27Cake\Database\Driver\Mysql\x27/\x27driver\x27 => \x27Cake\Database\Driver\Postgres\x27/g"  /path/to/file.ext

or

sed -i "s/'driver' => 'Cake\Database\Driver\Mysql'/'driver' => 'Cake\Database\Driver\Postgres'/g"  /path/to/file.ext

How can I make such a replacement?

Thank you!

Upvotes: 0

Views: 934

Answers (6)

SteveMc
SteveMc

Reputation: 65

None of the answers given worked for me exactly as they were written, so I've used these as inspiration for testing, and found this to work for me:

sed -i 's/\x27driver\x27 => \x27Cake\\\Database\\\Driver\\\Postgres\x27/\x27driver\x27 => \x27Cake\\\Database\\\Driver\\\Mysql\x27/g'  /path/to/file.ext

sed -i 's/\x27driver\x27 => \x27Cake\\\Database\\\Driver\\\Mysql\x27/\x27driver\x27 => \x27Cake\\\Database\\\Driver\\\Postgres\x27/g'  /path/to/file.ext

or, for the foo-bar example:

sed -i 's/\x27driver\x27 => \x27Cake\\\Database\\\Driver\\\Mysql\x27/\x27foo\x27 => \x27barx27/g'  /path/to/file.ext

Thank you all, particularly @Kent and @anubhava

Upvotes: 0

user557597
user557597

Reputation:

Not a Linux person, just guessing here.

What the Perl engine processor should see:

s/'driver' => 'Cake\\Database\\Driver\\Mysql'/'driver' => 'Cake\\Database\\Driver\\Postgres'/g

Single quote to command processor:

sed 's/\'driver\' => \'Cake\\\Database\\\Driver\\\Mysql\'/\'driver\' => \'Cake\\\Database\\\Driver\\\Postgres\'/g'  /path/to/file.ext

Double quote to command processor:

sed  "s/'driver' => 'Cake\\\\Database\\\\Driver\\\\Mysql'/'driver' => 'Cake\\\\Database\\\\Driver\\\\Postgres'/g"  /path/to/file.ext

Upvotes: 0

Tom Fenech
Tom Fenech

Reputation: 74615

This works for me using GNU sed and I'm not sure why it wouldn't be portable:

$ path='Cake\\Database\\Driver\\Mysql'
$ sed "s/'driver' => '${path}'/'foo' => 'bar'/" <<<"'driver' => 'Cake\\Database\\Driver\\Mysql'"
'foo' => 'bar'

Within double quotes, single quotes can be used literally. To make the sed line easier, I moved the path to a variable.

Upvotes: 1

Kent
Kent

Reputation: 195059

you have to escape the backslash: \:

kent$  sed "s#'driver' => 'Cake\\\\Database\\\\Driver\\\\Mysql'#'foo' => 'bar'#"<<<"'driver' => 'Cake\Database\Driver\Mysql'"   
'foo' => 'bar'

kent$  sed 's/\x27driver\x27 => \x27Cake\\Database\\Driver\\Mysql\x27/\x27foo\x27 => \x27bar\x27/'<<<"'driver' => 'Cake\Database\Driver\Mysql'"   
'foo' => 'bar'

Upvotes: 0

Etan Reisner
Etan Reisner

Reputation: 80931

This works in a quick test here:

sed "s/'driver' => 'Cake\\\Database\\\Driver\\\Mysql'/'driver' => 'Cake\\\Database\\\Driver\\\Postgres'/g"

Upvotes: 0

anubhava
anubhava

Reputation: 785146

You can use:

SQ=$'\x27'
sed "s/${SQ}driver${SQ} => ${SQ}Cake\\\\Database\\\\Driver\\\\Mysql${SQ}/${SQ}driver${SQ} => ${SQ}Cake\\\\Database\\\\Driver\\\\Postgres${SQ}/" file
'driver' => 'Cake\Database\Driver\Postgres'

You need to use \\\\ to match \ and to match single quote define a variable as shown above.

Upvotes: 1

Related Questions