3

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?

4 Answers 4

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"
4
  • I get command completion prompt from this :(
    – user13743
    Commented Apr 1, 2010 at 15:36
  • @user13743 - did you copy paste my solution. what type of shell do you have?
    – Nifle
    Commented Apr 1, 2010 at 15:39
  • Yeah, I copied and pasted your solution. $ echo $SHELL gives /bin/bash
    – user13743
    Commented Apr 1, 2010 at 15:48
  • @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
    Commented Apr 1, 2010 at 17:27
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
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"
1
  • this does not print the " in the second require_once
    – Nifle
    Commented Apr 1, 2010 at 15:41
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.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .