8

I have a bunch of .php files that I wanted to replace all occurrences of a string.

find: jQuery(function
replace: head.ready(function

I thought I was doing it right by using:

find . -name '*.php' -exec sed -e 's/jQuery[(]function/head.ready[(]function/g' -i'.bak' {} \;

What ended up happening is it replaced jQuery(function with head.ready[(]function

I was thinking I could escape the ( by enclosing it in blocks [] but thats not the case.

Does anybody have any suggestions?

3 Answers 3

14

( isn't a special character in sed regular expressions. You don't need to escape it.

sed -e 's/jQuery(function/head.ready(function/g'

[(] in a regex means a character set containing just one element, (. It's a convoluted way of writing (.

[(] in replacement text means the three characters [(]. Brackets have no special meaning in replacement text.

You can avoid repeating the function name if you like, by putting it in a group. Groups are delimited by backslash-parenthesis.

sed -e 's/jQuery(\(function\)/head.ready(\1/g'

Beware that your replacement will also affect jQuery(functionwithsuffix. The easy way to avoid this is to use a tool that understands extended Perl regular expressions, so you can use (?![^A-Za-z0-9_]) at the end of the search string, meaning “followed by something that isn't an alphanumeric character”. Note that in Perl regular expressions, ( is special, you need to prefix it with a backslash.

perl -pe 's/jQuery\(function(?![^A-Za-z0-9_])/head.ready(function/g'
perl -pe 's/jQuery\((function)(?![^A-Za-z0-9_])/head.ready($1/g'
5
  • Whether or not parens are literal or not differs between sed dialects, although this should be correct for most platforms. There is only one Perl so the Perl alternative might end up being the simplest if you need a portable solution (although even then you need different quoting if you need to be portable to Windows )-:
    – tripleee
    Commented Jun 28, 2013 at 5:36
  • 2
    @tripleee What bizarre sed implementation does not implement BRE (under which parentheses are literal)? Certainly not a historical Unix implementation, nor any of the major modern ones (BSD, GNU, BusyBox, …). Commented Jun 28, 2013 at 9:29
  • Sorry, I got mixed up. )-:
    – tripleee
    Commented Jun 29, 2013 at 3:11
  • Is ) similar to ( ?
    – Timo
    Commented Dec 28, 2017 at 11:56
  • Note that in perl regexps, [^A-Za-z0-9_] happens to be \W (or [^\w]). (?![^A-Za-z0-9_]) could also be replaced with \b. Commented May 18, 2020 at 9:36
5

There is no need to escape the brackets in the replacement string.

sed -e 's/jQuery[(]function/head.ready(function/g'
1
  • I need to replace: jQuery(function with head.ready(function.... i thought i needed to escape the "(" by including brackets around it... Commented Jun 27, 2013 at 23:14
3

( is a special character in sed, if using extended regular expression (ERE).

For example, sed -e will fail on Unmatched error, when you need to escape round brackets (for whatever reason), but run sed without specifying ERE:

$ regex="\("; echo "...(..." | sed 's/'$regex'/_/g'
sed: -e expression #1, char 8: Unmatched ( or \(

$ regex="\("; echo "...(..." | sed -e 's/'$regex'/_/g'
sed: -e expression #1, char 8: Unmatched ( or \(

In such case you'll have to use sed with -E option (or -r, --regexp-extended):

$ regex="\("; echo "...(..." | sed -E 's/'$regex'/_/g'
..._...

$ regex="\("; echo "...(..." | sed -r 's/'$regex'/_/g'
..._...
4
  • They are completely accurate. They did not mention extended regular expressions because the user in the question wasn't using extended regular expressions. Note also that the only issue in the user's code is in the replacement text.
    – Kusalananda
    Commented May 17, 2020 at 16:31
  • @Kusalananda, it's not accurate to say "( isn't a special character in sed regular expressions. You don't need to escape it." The rest of the answer is accurate of-course.
    – Noam Manos
    Commented May 18, 2020 at 9:23
  • Since sed uses basic regular expressions. Extended expressions with -E is a non-standard extension. Yes, most sed implementations can be made to use extended expressions, and then you have to escape the parentheses, but the user here doesn't use extended regular expressions, and it's not the default type of expressions for sed to use. Therefore, the other answers are not inaccurate. Possibly incomplete, but totally accurate.
    – Kusalananda
    Commented May 18, 2020 at 9:36
  • 1
    sure thing, it's all a matter of translating "not completely accurate". I removed that line, so my answer will be more accurate ;-)
    – Noam Manos
    Commented May 18, 2020 at 11:35

You must log in to answer this question.

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