.png)
Я пытаюсь заменить в одном из своих проектов все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)