Как добавить строку текста в середину файла, используя bash? - PullRequest
39 голосов
/ 19 июля 2011

Я пытаюсь добавить строку текста в середину текстового файла в bash-скрипте.В частности, я пытаюсь добавить сервер имен в мой файл /etc/resolv.conf.В своем нынешнем виде resolv.conf выглядит так:

# Generated by NetworkManager
domain dhcp.example.com
search dhcp.example.com
nameserver 10.0.0.1
nameserver 10.0.0.2
nameserver 10.0.0.3

Моя цель - добавить nameserver 127.0.0.1 над всеми другими строками сервера имен, но под любым текстом над нимВ конце я хочу, чтобы мой файл resol.conf выглядел так:

# Generated by NetworkManager
domain dhcp.example.com
search dhcp.example.com
nameserver 127.0.0.1
nameserver 10.0.0.1
nameserver 10.0.0.2
nameserver 10.0.0.3

Как это возможно с помощью сценария bash?Это что-то типа sed или awk?Или мой лучший ход - креативный поиск в файле?

Ответы [ 6 ]

40 голосов
/ 19 июля 2011

Вот решение с использованием sed:

$ sed -n 'H;${x;s/^\n//;s/nameserver .*$/nameserver 127.0.0.1\n&/;p;}' resolv.conf

# Generated by NetworkManager
domain dhcp.example.com
search dhcp.example.com
nameserver 127.0.0.1
nameserver 10.0.0.1
nameserver 10.0.0.2
nameserver 10.0.0.3

Как это работает: во-первых, подавьте вывод sed с помощью флага -n.Затем для каждой строки мы добавляем строку к пробелу, разделяя их новыми строками:

H

Когда мы подходим к концу файла (с адресом $), мы перемещаем содержимоепространство удержания для пространства образца:

x

Если первая строка в пространстве образца пуста, мы заменяем ее ничем.

s/^\n//

Затем мы заменяем первую строку, начинающуюся с nameserver строкой, содержащей nameserver 127.0.0.1, новой строкой (Ваша версия sed может не поддерживать \n, в этом случае замените n буквальным переводом строки) и исходную строку (представленную &):

s/nameserver .*$/nameserver 127.0.0.1\n&/

Теперь нам просто нужно распечатать результаты:

p
20 голосов
/ 19 июля 2011

Если вы хотите вставить сразу после строки search, это намного проще:

sed -ie '/^search/a nameserver 127.0.0.1' filename
  • -i: редактировать файл на месте
  • -e: разрешает выполнение скрипта / команд внутри выражения sed
  • a mynewtext: команда, которая говорит sed вставлять текст mynewtext после сопоставленного шаблона
8 голосов
/ 19 июля 2011

awk '/^nameserver/ && !modif { printf("INSERT\n"); modif=1 } {print}'

2 голосов
/ 19 июля 2011

Как насчет чего-то вроде:

sed -e ':a;N;$!ba;s/nameserver/nameserver 127.0.0.1\nnameserver/' /etc/resolv.conf

(аналогично этому: sed: Найти шаблон по двум строкам, а не заменять после него )

0 голосов
/ 16 сентября 2015

Вот решение Perl:

perl -lne 'if (not $f and /^nameserver/){ print "nameserver 127.0.0.1"; $f=1 }; print' resolv.conf

  • -n цикл вокруг каждой строки входного файла, не печатать автоматически каждую строку

  • -l удаляет символы новой строки перед обработкой и добавляет их потом

  • -e выполнить код perl

$f используется в качестве флага для указания того, что строка сервера имен уже найдена

0 голосов
/ 15 декабря 2011

Это может работать для вас:

 sed -e '/nameserver/{x;/./b;x;h;i\nameserver 127.0.0.1' -e '}' resolv.conf

Или GNU sed:

sed -e '0,/nameserver/{//i\nameserver 127.0.0.1' -e '}' resolv.conf
...