2016-06-29 3 views
0

Помогите мне с удалением некоторого блока из файла конфигурации dhcp с помощью sed. файл выглядит следующим образом:sed delete block

host dev1 { 
    host-identifier option agent.circuit-id "test1:418"; 
    fixed-address xxx.xxx.xxx.xxx; 
    option routers xxx.xxx.xxx.xxx; 
    option subnet-mask xxx.xxx.xxx.xxx; 
} 
host host2{ 
    host-identifier option agent.circuit-id "test2-:5"; 
    fixed-address xxx.xxx.xxx.xxx; 
    option routers xxx.xxx.xxx.xxx; 
    option subnet-mask xxx.xxx.xxx.xxx; 
} 

Я должен удалить блок для хоста, найденного схема идентификатора. Я сделал это с помощью команды:

sed -e '/^host\s*\S*\s*{\s*/ { N; /\s*test1:418/ { N; /[^host]/ { N; /[^host]/ { N; /[^host]/ { N; /[^host]/d}}}}}' -e '/^$/d' /path/to/file 

Но это не кажется приемлемым вообще ... :(

+0

'[^ host]' соответствует одному символу, который не является 'h',' o', 's' или' t'. Каждая строка в вашем примере содержит хотя бы один символ, который не является одним из них, поэтому каждая строка соответствует этому условию. – tripleee

+1

Многие диалекты 'sed' также не поддерживают расширения Perl, такие как' \ s' и т. Д. – tripleee

ответ

1

Если это сервер ISC DHCP я настоятельно рекомендую использовать omshell для изменения конфигурации

.

в противном случае, если у вас есть GNU gawk, следующий gawk команда может быть достаточно хорош для вас:

gawk '!/test2-:5/' RS='}\n' ORS='}\n' file 
      ^----------------------------------- ID goes here 

команда ограничена к GNU gawk, потому что он использует разделитель многострочных записей.

Объяснение:

Использование }\n как разделитель записей, AWK будет обрабатывать блок файла по блоку вместо строки-накрест режим по умолчанию. Значение AWK будет видеть эти записи:

host dev1 { 
    host-identifier option agent.circuit-id "test1:418"; 
    fixed-address xxx.xxx.xxx.xxx; 
    option routers xxx.xxx.xxx.xxx; 
    option subnet-mask xxx.xxx.xxx.xxx; 

и

host host2{ 
    host-identifier option agent.circuit-id "test2-:5"; 
    fixed-address xxx.xxx.xxx.xxx; 
    option routers xxx.xxx.xxx.xxx; 
    option subnet-mask xxx.xxx.xxx.xxx; 

На этих записях мы применяем регулярное выражение !/test2-:5/. Флаг ! отрицает матч. Нам не нужно указывать больше, поскольку awk будет по умолчанию печатать текущую запись, если условие оценивается до true. Поскольку вторая запись соответствует шаблону, она не будет напечатана.

\n} также для разделитель выходной записи добавляет закрывающий кронштейн при печати.


Btv, с sed Я хотел бы использовать цикл, основанный на этикетке (:a). Мы вводим пароль с /host .*{/ до закрытия } и добавляем все строки в буфер шаблонов. По завершении закрытия } мы проверяем, содержит ли буфер шаблона идентификатор. Если он содержит идентификатор, он будет удален:

sed '/host .*{/{:a;N;/}/!ba;/test2-:5/d}' file 
+0

Вы на 100% прав, это не работа для sed. Просто укажите его gawk-specific из-за множественного символа 'RS' или потеряйте' \ n' после '}'. –

+1

Я слишком привык к gawk! Благодарю. Кстати, на основании нашего вчерашнего обсуждения я вскоре передумал в BEGIN {RS = ORS = "\ n}"}!/Test2-: 5/'', но тогда я подумал, что double'} 'в конце блок «BEGIN» может смутить OP больше, чем помогает. Я лично предпочел бы, чтобы с этого момента в случаях, когда длина команды не является такой проблемой. – hek2mgl

+0

Спасибо. Вы правы, это не для sed, но я должен сделать это sed. Не спрашивайте, почему. :) Ваш ответ в порядке. –