избегая знака доллара - PullRequest
3 голосов
/ 23 июня 2011

У меня есть строка в файле my.cnf

datadir = /var/lib/mysql

Следующее изменяет его на mysql3307, как и ожидалось.

sed -i 's/\/var\/lib\/mysql$/\/var\/lib\/mysql3307/' /etc/my.cnf

Но если у меня есть следующее:

datadir = /var/lib/mysql/

Тогда следующее не меняет путь, как ожидалось:

sed -i 's/\/var\/lib\/mysql\/$/\/var\/lib\/mysql3307/' /etc/my.cnf

Я хочу изменить путь на mysql3307, где datadir - / var / lib / mysql (с / без /)

Обновление:

Вот проблема: Обе вышеуказанные команды работают на одном сервере, и ни одна из них не работает на другом.

Следующее работает, как и ожидалось, но мне нужно добавитьчто $ для обозначения строк, заканчивающихся mysql /

sed -i 's/\/var\/lib\/mysql\//\/var\/lib\/mysql3307/' /etc/my.cnf

Замечено:

Знак ^ работает как и ожидалось, а знак конца строки $ - нет.Любая подсказка?

Обновление:

Кажется, он работает после использования команды "dos2unix".

Ответы [ 3 ]

2 голосов
/ 23 июня 2011

Если ваше намерение состоит в том, чтобы изменить только пути, которые имеют этот конкретный каталог, вам нужно быть немного хитрее. Вы должны поймать его в конце строки без завершающего /, и вы также должны поймать его везде, где имеет завершающий / (конец строки или нет).

Но вы не хотите ловить такие вещи, как /var/lib/mysqlplus, поскольку это совершенно другой каталог .

Подумайте об использовании расширенных регулярных выражений и использовании другого символа-разделителя, чтобы ваша команда не выглядела как пила (/\/\/\/\/\/\/\/\). С этими изменениями и небольшим изменением самого регулярного выражения, оно отлично работает:

$ echo '
/var/lib/mysqlplus
/var/lib/mysql/
/var/lib/mysql
/var/lib/mysql/xyz' | sed -E 's|/var/lib/mysql([$/])|/var/lib/mysql3307\1|'

/var/lib/mysqlplus
/var/lib/mysql3307/
/var/lib/mysql
/var/lib/mysql3307/xyz
1 голос
/ 23 июня 2011

Использование $ в качестве литерального символа, возможно, необходимо экранировать, но не в качестве якоря, означающего конец строки.

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

sed -i `'s|/var/lib/mysql/|/var/lib/mysql13307/|' /etc/my.cnf
0 голосов
/ 23 июня 2011

Если вы специально хотите изменить только значение datadir, следующая команда более разумна:
sed -i.bak 's| *datadir *=.*|datadir = /var/lib/mysql3306/|g' /etc/my.cnf

Примечание: -i.bak резервная копия исходного файла с суффиксом .bak перед внесением изменения.

...