Intereting Posts
Определение того, какое приложение использует сетевой интерфейс Bash выполняет другой файл из запросившегося, даже если он предоставляет полный путь Bash: слияние имени папки из переменной с именем файла Загрузка нескольких похожих URL-адресов с использованием скобок Разница между запуском mke2fs и настройкой типа FS в cfdisk? Как установить диск на ключ в Red-Hat 6 (Beta) после его извлечения Создайте загрузочную постоянную систему USB Livesystem для UEFI Как установить ограничение nofile на rsyslog с выскочкой? Как отсортировать по 2 столбцам и сохранить верхнюю строку из каждой группы? Отсутствует файл конфигурации для SSSD? Как запустить пользовательскую службу Как я могу исправить громкого вентилятора в Linux? Как использовать цитату и доллар с помощью systemd как сжимать все изображения, jpg в каталоге в другой каталог, используя imagemagick Как я могу решить выходное шахматное явление в tmux

Как переформатировать блоки зоны named.conf в одну строку?

По причинам, о которых я здесь не буду говорить, мне нужно сделать копию старого файла named.conf сервера CentOS 5.10 и выполнить некоторые манипуляции с текстом. Окончательный результат должен объединить информацию о каждой зоне в одну отдельную строку. Кроме того, мне нужно написать его, чтобы он мог работать как задание cron. Вот пример того, с чего я начинаю:

 зона "."  {
         подсказка типа;
         файл "named.root";
 };

 зона "somedomain.com" {
         тип мастера;
         файл "somedomain.net";
         allow-Transfer {
                 11.11.11.11;
                 22.22.22.22;
                 общего позволяют-передачи;
         };
 };

 зона "otherdomain.com" {
         тип мастера;
         файл "otherdomain.com";
         allow-Transfer {
                 33.33.33.33;
                 44.44.44.44;
                 55.55.55.55;
                 общего позволяют-передачи;
         };
 };

И вот пример того, что должно появиться в отредактированном файле:

 зона "."  {подсказка типа;  файл "named.root";  };
 зона "somedomain.com" {тип мастера;  файл "somedomain.net";  allow-Transfer {11.11.11.11;  22.22.22.22;  общего позволяют-передачи;  };  };
 зона "otherdomain.com" {тип мастера;  файл "otherdomain.com";  разрешить перевод {33.33.33.33;  44.44.44.44;  55.55.55.55;  общего позволяют-передачи;  };  };

Мой ИТ-директор и я безуспешно искали существующие сценарии, которые преобразуют named.conf в формат «одна строка на зону». Используя tr и sed, мне удалось 1) превратить все вкладки в пробелы и 2) сжать несколько смежных пробелов в один пробел. Результат ближе к тому, что мне нужно, но у меня все еще возникают проблемы с удалением нежелательных новых строк при сохранении желаемых новых строк. Вот пример вывода, который близок к правильному:

 зона "."  {
  подсказка типа;
  файл "named.root"; 
 };
 зона "somedomain.com" {
  тип мастера;
  файл "somedomain.net";
  allow-Transfer {
  11.11.11.11;
  22.22.22.22;
  общего позволяют-передачи;
  };
 };
 зона "otherdomain.com" {
  тип мастера;
  файл "otherdomain.com";
  allow-Transfer {
  33.33.33.33;
  44.44.44.44;
  55.55.55.55;
  общего позволяют-передачи;
  };
 };

Протестировал несколько предложенных выражений sed, awk и tr для решения проблемы перевода строки, но ни одно из выражений не дало желаемого результата. Любые ваши предложения – даже общее направление, такое как «Эксперимент с sed и x, y, z» – будут очень благодарны. Спасибо!

Откройте файл в Vim (или просто vi ) и введите:

 :g/^zone/.,/^}/j 

Вуаля, вы сделали.


Это выполняет g lobally, на каждой строке, начинающейся с zone , команда:

 .,/^}/j 

Это означает, что от текущей строки ( . ) До следующей строки, которая начинается с закрывающей фигурной скобки, соедините все эти строки вместе.


Если вам нужно написать скрипт, используйте скриптовую форму vi , ex :

 printf '%s\n' 'g/^zone/.,/^}/j' x | ex file.txt 

Попробуй это:

 sed -n ' /^zone/,/^};/ H # append current line to hold space in this range /^};/ { # at the end of the range: s/.*// # erase the current line x # exchange pattern space with hold space s/\n// # remove first newline (before "zone") s/[[:space:]]\+/ /g # condense all other whitespace including newlines p # and print this zone record } ' named.conf 

результат

 zone "." { type hint; file "named.root"; }; zone "somedomain.com" { type master; file "somedomain.net"; allow-transfer { 11.11.11.11; 22.22.22.22; common-allow-transfer; }; }; zone "otherdomain.com" { type master; file "otherdomain.com"; allow-transfer { 33.33.33.33; 44.44.44.44; 55.55.55.55; common-allow-transfer; }; }; 

sed -e ':nextline' -e N -e 's/\n\s*\([^z]\)/\1/' -e 'tnextline' named.conf

Вы можете сделать это с помощью paragraph-mode инструментов awk и Perl и оператора range инструмента sed :

 sed -e ' /^zone/,/^$/!d H;/^zone/h;/^$/!{$!d;} g;s/[[:space:]]\{1,\}/ /g s/ $// ' input.file awk -vRS= '{$1=$1}1' input.file perl -pl -00e 's/\s+/ /g' input.file perl -pl -00e 'tr/\t\040\n/ /s' input.file 

Выход:

 zone "." { type hint; file "named.root"; }; zone "somedomain.com" { type master; file "somedomain.net"; allow-transfer { 11.11.11.11; 22.22.22.22; common-allow-transfer; }; }; zone "otherdomain.com" { type master; file "otherdomain.com"; allow-transfer { 33.33.33.33; 44.44.44.44; 55.55.55.55; common-allow-transfer; }; };