Изменить / сопоставить строку на n строк ниже определенного совпадения в Perl? - PullRequest
4 голосов
/ 31 октября 2019

Привет, недавно я опубликовал проблему. редактировать n-ю строку под соответствием строки в bash?
(Проблема: мне нужно отредактировать PROTOCOL строку на 3 строки ниже [MARATHON])

Это файл:

# /etc/ndxconfig.ini will override this file
# if APP_ID is added in service propery, service discovery will be using marathon;
# HOST/PORT specified will override values retrieved from marathon

[MARATHON]
HOSTS = {{ ','.join(groups['marathon'])}}
PORT = 8080
PROTOCOL = http
SECRET = SGpQIcjK2P7RYnrdimhhhGg7i8MdmUqwvA2JlzbyujFS4mR8M88svI7RfNWt5rnKy4WHnAihEZmmIUb940bnlYmnu47HdUHE


[MYSQL]
; APP_ID = /neon/infra/mysql
HOST = {{keepalived_mysql_virtual_ip}}
PORT = 3306
SECRET = tIUFN1rjjDBdEXUsOJjPEtdieg8KhwTzierD48JsgDeYc84DD6Uy5a6kzHfKolq1MNS1DKwlSqxENk33UulJd9DPHPzYCxFm

Проблема в том, что если я в некоторых случаях перезапущу скрипт,
sed '/\[MARATHON\]/{N;N;N;s/http/https/;}' <file> будет добавлять все больше и больше s к http (httpsssss).
Так что ядобавил бы положительный прогноз в регулярном выражении для s. Я могу сделать это с perl -pe , но не знаю, как я делаю это на n-й строке ниже совпадения . Пожалуйста помоги. Как я могу это сделать?

Ответы [ 2 ]

2 голосов
/ 31 октября 2019

Попробуйте эту однострочную строку, которая делает именно то, что вы просили: отредактируйте строку на n строк ниже некоторого конкретного соответствия в Perl . Но также рассмотрим NOTES ниже.

cat file | perl -lpe '
$seen = 1 if m{\[MARATHON\]}xms;
$num_lines++ if $seen;
s{ \A ( PROTOCOL \s+ = \s+ ) http }{${1}https}xms if $num_lines == 4;
'

NOTES:

Приведенный выше код отвечает на вопрос, но это плохой код. Почему? Обычно плохая идея разбирать известный широко используемый формат, полагаясь только на на ожидаемые шаблоны и ожидаемое количество строк. Здесь формат выглядит как .ini, поэтому рассмотрите возможность поиска модулей / библиотек, используемых для анализа / чтения / записи config ini файлов. Например:

Если вы не хотите использовать модули, подобные приведенным выше, по крайней мере, рассмотрите возможные будущие изменения ввода и используйте меньше предположений в своем коде. В этом случае предположение о n -ой строке из заголовка раздела кажется наименьшим надежным для изменения. Синтаксические анализаторы ini в исходном коде, которые пишут этот файл, могут не заботиться о порядке строк. Заголовки разделов более надежны. Возможно, прочитайте весь файл (slurp) и измените на https, используя не жадное многострочное регулярное выражение от [MARATHON] до PROTOCOL = http. Не указывайте точное количество строк, просто убедитесь, что изменяемая строка находится в том же разделе. Но это все еще изобретает колесо - избегайте, если можете.

СМОТРИТЕ ТАКЖЕ:

2 голосов
/ 31 октября 2019

Если вы используете GNU sed, решение может использовать границы слов:

sed '/\[MARATHON\]/{N;N;N;s/\<http\>/https/;}' file 
#                          ^^     ^^

Вы также можете использовать детали контекста. Поскольку http после PROTOCOL, вы можете просто использовать это для сброса значения:

sed '/\[MARATHON\]/{N;N;N;s/\(.*= *\).*/\1https/;}' file 

\(.*= *\).* будет сопоставлять и захватывать ключ с = и дополнительными пробелами, и его значение равновосстанавливается с помощью \1, в то время как https всегда будет перезаписывать значение.

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