I'm trying to replace in one of my projects all mysql to mysqli, with their parameters. To do so, I'm searching for all files with mysql in my folder recursively and replacing it with mysqli.


mysql_query($query) to mysqli_query($link, $query)

I'm able to capture everything (according to Regex tester) but nothing seemed to be replaced, and no errors as well.

grep -rl mysql PROJECTFILE | xargs sed -ri "s/(mysql_query)\(\$([\w-]+)\)/WhatIWant/g"

I have read about backslashes in sed but didn't quite get it; the output has no errors but the file remains the same. If I can only know what is missing with an example or explanation, that would be perfect.

It's easy to replace mysql to mysqli, but it would be nice to do it all at once. I'm using a temporary file just to make sure it works before I can try it on in my project.


EDIT: I know if I want to do it all at once I have to capture mysql on its own and add an i, but that was just a thought.

For tedron, my desired output would be similar to this.

sed -ri "s/(mysql_query)\(\$([\w-]+)\)/mysqli_query($link, \2)/g" filename

glenn suggested a solution with no capturing. However, if I want to modify mysql_fetch_array($query), then I may have to use regex to keep the first parameter and append MYSQLI_BOTH for example.


Thanks to tedron, I was able to solve my problem according to my way:

sed -ri 's/(mysql)_query\((\$[a-zA-Z_-]+)\)/\1i_query($link, \2)/' filename

And for mysqli_fetch_array:

sed -ri 's/(mysql)(_fetch_array)\((\$[a-zA-Z_-]+)\)/\1i\2(\3, MYSQLI_BOTH)/' filename

Use this with grep as I did in my question to modify a directory at once.

  • Could you show us i) an example of your input ii) your desired output and iii) the actual command you used? Not "WhatIWant", bu the exact command you tried. – terdon Nov 18 '14 at 0:46
  • @terdon I gave an example, WhatIWant could be anything. And my issue is that sed is not capturing the regex part although it is correct. – Atieh Nov 18 '14 at 14:36
  • It's not correct, that's why we needed to see it :). Please also show your input though. You have both ( ) and \( \) which is what is causing the issue but I can't give a precise answer without seeing both input and desired output. – terdon Nov 18 '14 at 15:35
  • @terdon please check my edit – Atieh Nov 18 '14 at 16:28

The problem is the \w. I only found this out myself when attempting to figure out what's going on here, but apparently, things like \s or \w which are already character classes cannot be used inside other character classes with ERE (they can with PCREs). To illustrate:

$ echo foo- | sed -r 's/[\w-]+/bar/'
$ echo 'w\-foo' | sed -r 's/[\w-]+/bar/'
$ echo foo- | sed -r 's/\w+/bar/'

So, the character escape classes are treated as literal characters when inside a [ ] character class. The expression [\w-] means "match any of \,w or -.

To make your regular expression work, either use [a-zA-z_] instead of \w or use grouping parentheses:

$ echo 'mysql_query($query)' | 
    sed -r 's/mysql_query\(\$(\w|-)+\)/WhatIWant/'

Specifically for your example:

$ echo 'mysql_query($query)' | 
    sed -r 's/(mysql_query)\((\$[a-zA-Z_-]+)\)/\1($link,\2)/'
  • I sensed it! I actually tried [a-zA-Z_-] yesterday but maybe I have missed something. I will get back to you tonight and see how it goes. Thanks! – Atieh Nov 18 '14 at 20:44

You don't need to capture anything:

sed 's/mysql_query(/mysqli_query($link, /g' file

Don't use -i while you're testing, add that when you're satisfied with the results.

  • He's testing on a temporary copy, so -i is OK. – Barmar Nov 17 '14 at 22:02
  • I would like to capture in this one because I will be using it similarly for other mysql like fetch_array and the like. I shall test your answer and let you know. – Atieh Nov 17 '14 at 23:38

Yet another possibility using extended regexp (-r):

sed -r 's/(mysql)(_query\()/\1i\2$link,/g'

You don't need a capture group around mysql_query, because you're not copying that into the replacement. You only need to capture the query argument, since that varies in each call.

sed -ri 's/mysql_query\s*\((\$\w+)\)/mysqli_query($link, \1)/g'

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.