#string #sed #replace
Вопрос:
Я пытаюсь написать сценарий bash, но в данный момент я застрял.
Допустим, у меня есть следующий файл:
targets {
type = pppcfg_target_internet;
name = "internet";
only_crypt_auth = no;
local {
username = "";
passwd = "";
Я хотел бы заменить имя пользователя и пароль.
Проблема в том, что этот раздел существует несколько раз, за исключением второй строки.
Итак, что я хотел бы сделать:
Замените «имя пользователя» и «пароль«, если есть «тип = pppcfg_target_internet;» несколькими строками ранее.
Предпочтительно, я хотел бы сохранить его достаточно гибким, чтобы мне не нужно было устанавливать его в точную строку на случай, если код немного изменится или будет добавлена строка.
Итак, «Если в 5-10 строках над строкой поиска есть «pppcfg_target_internet«, замените «пароль» и «имя пользователя«.
Я буду рад получить любую помощь. Также для рекомендации, следует ли использовать «ask» или «sed».
Ответ №1:
Вы можете использовать sed для выбора диапазона текста между определенными строками, которые вы хотите заменить, например, следующим образом
sed '/pppcfg_target_internet/,/}/s/passwd.*/passwd = "newpass"/g'
Это означает, что между строками с «pppcfg_target_internet» и «}» найдите и замените строку, начинающуюся с passwd, следующей строкой: ‘passwd = «newpass»‘
Может быть, было бы неплохо создать какое-нибудь уникальное окончание блока
Комментарии:
1. Большое спасибо! Надеюсь, вы не возражаете, если я немного расширю свой вопрос. Допустим, строка, которую я хочу заменить, находится в «FILE_A.txt» и я хочу заменить его строкой из «FILE_B.txt». Как бы мне пришлось корректировать ваше предложение, если бы я работал в двух разных файлах?
2. Если FILE_B.txt содержит одну строку, вы можете прочитать ее раньше. По умолчанию команда чтения будет считывать строку в переменную ОТВЕТА:
read FILE_B.txt amp;amp; sed "/pppcfg_target_internet/,/}/s/passwd.*/passwd = "$REPLY"/g"
Ответ №2:
Это может сработать для вас (GNU sed):
sed -E '/^[^n]*pppcfg_target_internet/{:a;N;/passwd/!ba
s/^([^n]*n){5,10}[^n]*$/amp;/;Tb
s/(username = ).*/1"new user";/m
s/(passwd = ).*/1"new pass";/m};:b;P;D' file
Соберите строки между type = pppcfg_target_internet;
и passwd
, а затем замените новые значения пользователя и пароля.
N. B. Использование m
флага в команде substitute для обеспечения подстановки происходит только для этой совпадающей строки. Также обратите внимание, что если количество собранных строк меньше 5 или больше 10, коллекция игнорируется.
Комментарии:
1. Большое вам спасибо, к сожалению, это для меня не работает.