Как добавить строку текста в середину файла с помощью bash? - программирование

Как добавить строку текста в середину файла с помощью bash?

Я пытаюсь добавить строку текста в середину текстового файла в bash script. В частности, я пытаюсь добавить сервер имен в файл /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 script? Это что-то sed или awk? Или будет ли творческий greping для воссоздания файла лучшим моментом?

4b9b3361

Ответ 1

Вот решение, использующее 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 на литерал newline) и исходной линией (представленной &):

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

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

p

Ответ 2

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

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

Ответ 3

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

Ответ 5

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

 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

Ответ 6

Здесь решение Perl:

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

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

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

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

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