Где это выражение Regex не закрыто в sed (апострофная скобка)? - PullRequest
1 голос
/ 04 мая 2019

Я пытаюсь обновить некоторые настройки для WordPress, и мне нужно использовать sed. Когда я запускаю приведенную ниже команду, кажется, что строка не закончена. Что я делаю не так?

$ sed -i 's/define\( \'DB_NAME\', \'database_name_here\' \);/define\( \'DB_NAME\', \'wordpress\' \);/g' /usr/share/nginx/wordpress/wp-settings.php
> ^C

Спасибо.

Ответы [ 2 ]

4 голосов
/ 04 мая 2019

Одиночные кавычки в большинстве оболочек не поддерживают экранирование.Если вы хотите включить одинарную кавычку, вам нужно закрыть одинарные кавычки и добавить одинарную кавычку - либо в двойные кавычки, либо с обратной косой чертой:

 sed 's/define\( '\''DB_NAME'\'', '\''database_name_here'\'' \);/define\( '\''DB_NAME'\'', '\''wordpress'\'' \);/g'

Боюсь, это все равно не сработает для вас,поскольку \( особенный в седе.Вы, вероятно, хотите просто ( вместо

1007 *

или

sed 's/define( '"'"'DB_NAME'"'"', '"'"'database_name_here'"'"' );/define( '"'"'DB_NAME'"'"', '"'"'wordpress'"'"' );/g'
1 голос
/ 04 мая 2019

Обычно целесообразно использовать одинарные кавычки вокруг скрипта sed.Это тот случай, когда двойные кавычки были бы лучшим выбором - в сценарии sed нет метасимволов, кроме одинарных кавычек:

sed -e "s/define( 'DB_NAME', 'database_name_here' );/define( 'DB_NAME', 'wordpress' );/g" /usr/share/nginx/wordpress/wp-settings.php

или:

sed -e "s/\(define( 'DB_NAME', '\)database_name_here' );/\1wordpress' );/g" /usr/share/nginx/wordpress/wp-settings.php

илиeven:

sed -e "/define( 'DB_NAME', 'database_name_here' );/s/database_name_here/wordpress/g" /usr/share/nginx/wordpress/wp-settings.php

Еще один вариант, который следует рассмотреть, - это использование sed -f для предоставления сценария в виде файла.Это избавляет вас от необходимости скрывать содержимое сценария из оболочки.Недостатком может быть то, что вам нужно создать файл, запустить sed, используя его, а затем удалить файл.Вероятно, это слишком больно для текущей задачи, но это может быть разумно - это, безусловно, может облегчить жизнь, когда вам не нужно беспокоиться о побегах оболочки.

Я не уверен, что gопция (глобальная замена) актуальна;сколько отдельных строк вы найдете в файле настроек, содержащем две независимые define DB_NAME операции со значением по умолчанию?

Вы можете добавить опцию -i, когда у вас будет работать основной код.Обратите внимание: если вы когда-либо работали в macOS или системе на основе BSD, вам нужно будет указать суффикс в качестве дополнительного аргумента для опции -i (например, -i '' для нулевого суффикса или без резервного копирования; или -i.bak, чтобы иметь возможность надежно работать как на Linux (или, точнее, на GNU sed), так и на macOS и BSD (или, точнее, на BSD sed). Обращение к POSIX не поможет;• не поддерживает параметр перезаписи.

Контрольный пример (первый пример):

$ echo "define( 'DB_NAME', 'database_name_here' );" |
> sed -e "s/\(define( 'DB_NAME', '\)database_name_here' );/\1wordpress' );/g" 
define( 'DB_NAME', 'wordpress' );
$

Если интервал вокруг 'DB_NAME' не согласован, то вы получите более подробные регулярные выражения, используя [[:space:]]* вместо пробелов, вы найдете третий вариант лучше, чем другие, но второй может охватить как начальный, так и конечный контексты и использовать оба захвата при замене.

Прощальные слова : этот метод работает на этот раз, потому что шаблоны не включают метасимволы оболочки, такие как $ или ` . Очень часто сценарий должен соответствовать им, а затем использовать в основном одинОстальные аргументы сценария разумны.Для решения другой задачи - замените $DB_NAME во входных данных значением переменной оболочки $DB_NAME (оставив $DB_NAMEORHOST без изменений):

sed -e 's/$DB_NAME\([^[:alnum:]]\)/'"$DB_NAME"'\1/'

Есть три отдельные строки оболочки, все соединенные безпространства.Первый состоит из одинарных кавычек и содержит часть s/…/ команды s/…/…/;вторая - "$DB_NAME", значение переменной оболочки, заключенное в двойные кавычки, так что если значение $DB_NAME равно «автономная запись транспортного средства», у вас все еще будет один аргумент для sed;третья - это часть '\1/', которая возвращает любой символ, следующий за $DB_NAME во входном тексте (с учетом того, что если $DB_NAME может появиться в конце строки ввода, это не будет соответствовать).

Большинство регулярных выражений имеют нечеткое сопоставление;Вы должны учитывать различия в том, что может быть во входных данных, чтобы определить, насколько усердно должны работать ваши регулярные выражения для точной идентификации материала.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...