Can't escape single quotes in shell

3

1

I'm trying to make a command to do a perl substitution on a batch of php files in a directory. The string I want to replace has single quotes in it, and I can't get it to properly escape the in shell.

I tried echoing the string with unescaped quotes, to see what perl would be getting:

echo 's/require_once\('include\.constants\.php'\);/require_once\('include\.constants\.php'\);require_once\("\./functions/include\.session\.inc\.php"\);/g'

and it doesn't have the single-quotes in the result:

s/require_once\(include.constants.php\);/require_once\(include.constants.php\);require_once\("\./functions/include\.session\.inc\.php"\);/g

However, when I try to escape the single quotes:

echo 's/require_once\(\'include\.constants\.php\'\);/require_once\(\'include\.constants\.php\'\);require_once\("\./functions/include\.session\.inc\.php"\);/g'

I get the prompt to complete the command:

>

What I want it to parse to is this:

s/require_once\('include.constants.php'\);/require_once\('include.constants.php'\);require_once\("\./functions/include\.session\.inc\.php"\);/g

What am I doing wrong?

user13743

Posted 2010-04-01T15:22:01.730

Reputation: 1 571

Answers

1

Use " instead of ' on the outside, then you only have to escape two " inside the expression.

echo "s/require_once\('include.constants.php'\);/require_once\('include.constants.php'\);require_once\(\"\./functions/include\.session\.inc\.php\"\);/g"

Nifle

Posted 2010-04-01T15:22:01.730

Reputation: 31 337

I get command completion prompt from this :( – user13743 – 2010-04-01T15:36:47.800

@user13743 - did you copy paste my solution. what type of shell do you have? – Nifle – 2010-04-01T15:39:52.550

Yeah, I copied and pasted your solution. $ echo $SHELL gives /bin/bash – user13743 – 2010-04-01T15:48:20.553

@user13743 - Try just echo "s/require_once\('include" if that works add some more of the string echo "s/require_once\('include.constants.php'\);/". Repeat until it breaks. This should narrow down the error. – Nifle – 2010-04-01T17:27:19.083

1

No expansion or evaluation of any kind takes place inside a single-quoted string, not even backslash escapes. As Nifle and canen posted, use double-quotes instead, and escape those instead of the single quotes. However, you only need to escape them for your shell's benefit. If you plan to use this s/// directly inside a perl script, no escaping is necessary because you normally wouldn't enclose s/// in quotes to begin with.

Additionally, your s/// operation will fail because you have your delimiter character / in your replacement string. Either backslash-escape the slashes in /functions/include:

s/require_once\('include.constants.php'\);/require_once\('include.constants.php'\);require_once\("\.\/functions\/include\.session\.inc\.php"\);/g

or choose a different delimiter:

s@require_once\('include.constants.php'\);@require_once\('include.constants.php'\);require_once\("\./functions/include\.session\.inc\.php"\);@g

James Sneeringer

Posted 2010-04-01T15:22:01.730

Reputation: 448

0

Why not use double quotes?

"s/require_once\('include.constants.php'\);/require_once\('include.constants.php'\);require_once\("\./functions/include\.session\.inc\.php"\);/g"

canen

Posted 2010-04-01T15:22:01.730

Reputation: 244

this does not print the " in the second require_once – Nifle – 2010-04-01T15:41:59.443

0

You escape single quotes with a single quotes. For example, let's say you wanted to make a git commit with the following message: Updated BaseActiveRecord's save() method.

To do this, run the following command (and note that I escape the single quote with a single quote).

git commit -m 'Updated BaseActiveRecord''s save() method.'

You could also accomplish your goal using double quotes (and not escaping the single):

git commit -m "Updated BaseActiveRecord's save() method."

However, do note that double quotes on the command line cause certain things to get expanded (i.e. $vars). Hope this helps.

John Erck

Posted 2010-04-01T15:22:01.730

Reputation: 101