Не удается найти работающий шаблон sed

#sed #escaping #awstats

#sed #экранирование #awstats

Вопрос:

Я пытаюсь выполнить замену строки в нескольких сотнях конфигурационных файлов awstats и использую sed для этого. Однако у меня возникли проблемы с получением рабочего шаблона.

Если быть точным, я пытаюсь преобразовать эту строку в конфигурациях:

 HostAliases="REGEX[^.*example.com$]"
  

в это:

 HostAliases="REGEX[.example.com$]"
  

где example.com — вариант.

Я перепробовал десятки вариантов команды sed. Например:

 sed -i 's/^HostAliases="REGEX[^.*/HostAliases="REGEX[./' /etc/awstats/*.conf

sed -i 's/REGEX[^.*/REGEX[./' /etc/awstats/*.conf
  

но каждый раз выдается ошибка типа: sed: -e expression #1, char 49: unterminated 's' command

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

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

Ответ №1:

Первый аргумент ‘s’ сам по себе является регулярным выражением. Поэтому вам нужно экранировать (с ) специальные символы. В вашем случае это [ , . и * . Так что это должно быть:

 sed -i 's/^HostAliases="REGEX[^\.*/HostAliases="REGEX[./' /etc/awstats/*.conf
sed -i 's/REGEX[^\.*/REGEX[./' /etc/awstats/*.conf
  

Комментарии:

1. Спасибо, ваш ответ заставил меня правильно подумать, поэтому я мог бы решить свою собственную проблему. На самом деле мне нужна была команда sed sed -i 's/^HostAliases="REGEX[^\.*/HostAliases="REGEX[\./' /etc/awstats/*.conf . Я присуждаю балл за лучшее объяснение.

Ответ №2:

Это то, что вы имеете в виду?

 $ echo 'HostAliases="REGEX[^.*example.com$]"' | sed 's/^HostAliases="REGEX[^\.*/HostAliases="REGEX[\./'
  

Выводит:

 HostAliases="REGEX[.example.com$]"
  

Комментарии:

1. 1 за рабочий ответ и за то, что научил меня лучшему способу отладки. Я принимаю ответ Яна, потому что он научил меня, почему.

Ответ №3:

Вам также нужно экранировать специальные символы регулярного выражения, например:

 sed -i 's/REGEX[^\.*/REGEX[\./' /etc/awstats/*.conf
  

Ответ №4:

Вы забыли экранировать некоторые символы, такие как ^ и [ . Ваш sed будет примерно таким:

 sed -e 's/REGEX[^.*/REGEX[/' -i /etc/awstats/*conf