Команда SED не заменяет (рабочее регулярное выражение)

Команда SED не заменяет (рабочее регулярное выражение)

Я пытаюсь заменить в одном из своих проектов всеmysql в mysqli, с их параметрами. Для этого я рекурсивно ищу все файлы с mysql в своей папке и заменяю их на mysqli.

Бывший:

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

Мне удалось захватить все (согласно тестировщику Regex), но, похоже, ничего не было заменено, и ошибок тоже.

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

Я читал об обратных косых чертах вседно не совсем понял; вывод без ошибок, но файл остался прежним. Если бы я мог только узнать, чего не хватает с примером или объяснением, это было бы идеально.

Легко заменить mysql на mysqli, но было бы неплохо сделать все это сразу. Я использую временный файл, чтобы убедиться, что он работает, прежде чем я смогу попробовать его в своем проекте.

Спасибо.

РЕДАКТИРОВАТЬ: Я знаю, что если я хочу сделать все это сразу, мне нужно захватитьmysqlсам по себе и добавитья, но это была всего лишь мысль.


Для tedron мой желаемый результат будет примерно таким.

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

glenn предложил решение без захвата. Однако, если я хочу изменитьmysql_fetch_array($запрос), то мне, возможно, придется использовать регулярное выражение, чтобы сохранить первый параметр и добавитьMYSQLI_BOTHнапример.


РЕШЕНИЕ:

Благодаря tedron я смог решить свою проблему по своему способу:

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

И для mysqli_fetch_array:

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

Используйте это так же grep, как я сделал в своем вопросе, чтобы изменить каталог сразу.

решение1

Вам не нужно ничего снимать:

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

Не используйте -iво время тестирования, добавьте, когда будете удовлетворены результатами.

решение2

Еще одна возможность использования расширенного регулярного выражения ( -r):

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

решение3

Вам не нужна группа захвата вокруг mysql_query, потому что вы не копируете это в замену. Вам нужно только захватить аргумент запроса, так как он меняется в каждом вызове.

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

решение4

Проблема в \w. Я сам это обнаружил, когда пытался понять, что здесь происходит, но, по-видимому, такие вещи, как \sили \w, которые уже являются классами символов, не могут использоваться внутри других классов символов с ERE (они могут использоваться с PCRE). Для иллюстрации:

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

Таким образом, классы экранирования символов рассматриваются как литеральные символы внутри [ ]класса символов. Выражение [\w-]означает «соответствует любому из \, wили -.

Чтобы ваше регулярное выражение работало, используйте [a-zA-z_]вместо \wили используйте группирующие скобки:

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

Конкретно для вашего примера:

$ echo 'mysql_query($query)' | 
    sed -r 's/(mysql_query)\((\$[a-zA-Z_-]+)\)/\1($link,\2)/'
mysql_query($link,$query)

Связанный контент