LINUX.ORG.RU

sed, найти строки и заменить/удалить вторую


0

1

Никак не могу решить задачу, нужно в /etc/resolv.conf заменить/удалить второй по счету dns адрес. Думаю алгоритм примерно такой: Найти все строки начинающиеся с nameserver и ко второй найденной применить патерн, но как это реализовать, вообще не догоняю.

Написал вот:

sudo sed -i 's/^[^#]*nameserver.*/nameserver 123.123.123.123/' /etc/resolv.conf

Но он по понятным причинам заменяет все строки. Как применить патерн ко второй найденной строке ?

★★

Ответ на: комментарий от adriano32

У Вас там немного не то, что мне надо. Вот файл:

# Generated by dhcpcd from eth0
# /etc/resolv.conf.head can replace this line
nameserver 10.0.5.9
nameserver 10.0.5.7
nameserver 192.168.1.1
# /etc/resolv.conf.tail can replace this line

Нахожу все строки у которых в начале nameserver

nameserver 10.0.5.9
nameserver 10.0.5.7
nameserver 192.168.1.1
А вот теперь из этого найденного,во второй строке делаем замену
nameserver 10.0.5.9
nameserver 123.123.123.123
nameserver 192.168.1.1

Вот как так сделать, ткните пальцем, я уже 6 часов над этой проблемой сижу!

aivs ★★
() автор топика
Ответ на: комментарий от arsi

Вот таким скриптом изменяется вторая строка:

sed -n /nameserver/p /etc/resolv.conf | sed '2s/.*/nameserver 123123/'
А в resolv.conf это как записать ?

aivs ★★
() автор топика
Ответ на: комментарий от arsi

круто, работает, а на sed возможно такое сделать ??

aivs ★★
() автор топика
Ответ на: комментарий от arsi

Вечно то perl свой притулите, то руби, то пайтон. Человек попросил на sed, дайте на sed.

$ cat file
# Generated by dhcpcd from eth0
# /etc/resolv.conf.head can replace this line
nameserver 10.0.5.9
nameserver 10.0.5.7
nameserver 192.168.1.1
# /etc/resolv.conf.tail can replace this line
$ sed '0,/^[^#]*nameserver.*/{n;s/^[^#]*nameserver.*/nameserver\ 123\.123\.123\.123/;}' file
# Generated by dhcpcd from eth0
# /etc/resolv.conf.head can replace this line
nameserver 10.0.5.9
nameserver 123.123.123.123
nameserver 192.168.1.1
# /etc/resolv.conf.tail can replace this line
правда из-за «0,» работать будет только в GNU sed

adriano32 ★★★
()
Ответ на: комментарий от adriano32

Работает, спасибо! Как можно таким же способом 1,3,4 строку обработать ? И если можно прокомментировать скрипт

aivs ★★
() автор топика
Ответ на: комментарий от MKuznetsov

Подредактировал, честно не понял, что сделал, но работает Изменить первую строку

sudo sed -i '1,/^[^#]*nameserver.*/{n;n;s/^[^#]*nameserver.*/nameserver\ 123\.123\.123\.124/;}' /etc/resolv.conf
Изменить вторую строку
sudo sed -i '2,/^[^#]*nameserver.*/{n;n;s/^[^#]*nameserver.*/nameserver\ 123\.123\.123\.124/;}' /etc/resolv.conf
Изменить третью строку
sudo sed -i '3,/^[^#]*nameserver.*/{n;n;s/^[^#]*nameserver.*/nameserver\ 123\.123\.123\.124/;}' /etc/resolv.conf

aivs ★★
() автор топика
Ответ на: комментарий от aivs

0,
Сработать единственный раз на первом совпадении
/^[^#]*nameserver.*/
найти незакомментированную строчку с nameserver (тут возможная засада, подумайте почему, вспомните, только ли hash комментирует строку и не может ли nameserver попасться в какой-то другой части строки с другой опцией
{
начать обработку блока
n;
перейти к строке, следующей, за найденной по первому регекспу
s/^[^#]*nameserver.*/nameserver\ 123\.123\.123\.123/;
заменить то, что нашли на nameserver 123.123.123.123
}
закончить блок команд

adriano32 ★★★
()
Ответ на: комментарий от adriano32

Не вариант. Если между первым и вторым вхождением nameserver есть строки с иными данными, то твой скрипт не сработает:

$ cat file 
# Generated by dhcpcd from eth0
# /etc/resolv.conf.head can replace this line
nameserver 10.0.5.9
# some other stuff
nameserver 10.0.5.7
nameserver 192.168.1.1
# /etc/resolv.conf.tail can replace this line
$ sed '0,/^[^#]*nameserver.*/{n;s/^[^#]*nameserver.*/nameserver\ 123\.123\.123\.123/;}' file # твой вариант
# Generated by dhcpcd from eth0
# /etc/resolv.conf.head can replace this line
nameserver 10.0.5.9
# some other stuff
nameserver 10.0.5.7
nameserver 192.168.1.1
# /etc/resolv.conf.tail can replace this line
$ sed '/^[^#]*nameserver.*/{:l;n;s/^[^#]*nameserver.*/nameserver\ 123\.123\.123\.123/;t;bl}' file # Корректно работающий скрипт без GNU расширений
# Generated by dhcpcd from eth0
# /etc/resolv.conf.head can replace this line
nameserver 10.0.5.9
# some other stuff
nameserver 123.123.123.123
nameserver 192.168.1.1
# /etc/resolv.conf.tail can replace this line
$ 

Последовательность команд «t;bl» в данном случае можно заменить на GNUтую команду «Tl».

kim-roader ★★
()
Ответ на: комментарий от kim-roader

Тут даже хуже. Если первое совпадение у тебя было на чётной строке, то ломается всё:

$ cat file 
# Generated by dhcpcd from eth0
nameserver 10.0.5.9
nameserver 10.0.5.7
nameserver 192.168.1.1
# /etc/resolv.conf.tail can replace this line
$ sed '0,/^[^#]*nameserver.*/{n;s/^[^#]*nameserver.*/nameserver\ 123\.123\.123\.123/;}' file
# Generated by dhcpcd from eth0
nameserver 123.123.123.123
nameserver 10.0.5.7
nameserver 123.123.123.123
# /etc/resolv.conf.tail can replace this line
$

А всё потому что блок команд в скобках ты выполняешь для каждой из строк до первого вхождения nameserver и перепрыгиваешь своим n только нечётные строки внутри pattern space.

kim-roader ★★
()
Ответ на: комментарий от kim-roader

Ты прав, безусловно. Но у меня был файл и то, что из него надо сделать. Задание выполнено? Выполнено. Заказчик доволен? Доволен. А универсальность можно оттачивать до бесконечности...

adriano32 ★★★
()

гулять, так на все деньги

sed -i "$(awk '/nameserver/{print FNR}' /etc/resolve | awk '(NR==2)') s/nameserver.*/nameserver 123.123.123.123/" /etc/resolve
zolden ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.