Я использовал sed для удаления строк с определенными словами:
string=${line##* }
sed "/$string/d" $dhcp
Неудобство в том, что есть части текста, которые я не могу безопасно удалить.
В идеале это будет выглядеть примерно так:
пример: Вход:
config host
mac '00:a0:00:00:00:00'
option name 'laptop1'
option dns '1'
config host
option mac '00:a0:00:00:00:00'
option name 'string'
option dns '1'
config host
option name 'laptop3'
mac '00:a0:00:00:00:00'
option dns '1'
Выход
config host
option mac '00:a0:00:00:00:00'
option name 'laptop1'
option dns '1'
config host
option name 'laptop3'
mac '00:a0:00:00:00:00'
option dns '1'
Какой способ лучше всего подходит для этого?
благодарен за внимание
Не позволяйте переменной оболочки (особенно не заключенной в кавычки) расширяться, чтобы стать частью тела сценария оболочки. См. cfajohnson.com/shell/cus-faq-2.html#Q24. Наиболее распространенный способ использования значения переменной оболочки внутри этого сценария awk - это awk -v RS= -v ORS='\n\n' -v str = "$string" '$0!~str' file.
Спасибо, это очень хорошо сработало в переменных с большим количеством слов.


cat $dhcp | tr '\n' '\r' | sed -e "s/\r\r.*'string'.*\r\r/\r\r/" | tr '\r' '\n'
Объясняя:
tr '\n' '\r': \n на \r, чтобы позволить sed работать с «линиями разрыва».sed -e "s/\r\r.*'string'.*\r\r/\r\r/": 'string' и его родственные символы, пока не найдете строки с двойным разрывом.tr '\r' '\n': \r от \nСледующий awk может вам в этом помочь.
awk '/config host/{if (val){print val};non_flag=val = ""} /option name \047string\047/{non_flag=1;val = ""} !non_flag && NF{val=val?val ORS $0:$0} END{if (val){print val}}' Input_file
Добавляем и не однослойную форму раствора.
awk '
/config host/{
if (val){
print val};
non_flag=val = ""
}
/option name \047string\047/{
non_flag=1;
val = ""
}
!non_flag && NF{
val=val?val ORS $0:$0
}
END{
if (val){
print val}
}' Input_file
Объяснение: Теперь добавляем объяснение и для вышеприведенного кода.
awk '
/config host/{ ##Searching for text config host in a line if it is there then do following.
if (val){ ##If variable val is NOT NULL then do following.
print val}; ##printing the value of variable val here.
non_flag=val = "" ##Nullifying the variables non_flag and val here.
}
/option name \047string\047/{ ##Searching for string option name 'string' here if it is found then do following.
non_flag=1; ##Setting up the value of variable non_flag as 1 here.
val = "" ##Nullifying the variable named val here.
}
!non_flag && NF{ ##Checking conditions if variable non_flag is NULL and line is NOT a empty line then do following.
val=val?val ORS $0:$0 ##Create variable named val and each time cursor comes here concatenate its value with its own value.
}
END{ ##Starting END section of awk code here.
if (val){ ##Checking if variable val is NOT NULL then do following,
print val} ##Printing variable val value here.
}' Input_file ##Mentioning Input_file name here.
ПРИМЕЧАНИЕ: Если вы Input_file - это переменная оболочки, которая выглядит как из вашего сообщения, измените Input_file на "$dhcp".
** awk **
set str1=laptop1 ; //set string for removed section
awk -v RS = "config host" -v a=$str '($0!~a)&&(NR>1) {printf "%s", RS $0 }' file
1)RS = "config host" - установить разделитель записей на требуемую строку.
2)-v str1=$str1 получить аргумент (строка для поиска в записанной строке, в нашем случае $str1=laptop1).
3)($0!~str1)&&(NR>1) - записи, не содержащие строку $str.
4){printf "%s",RS $0 } - распечатать разделитель записей и записанную строку
Вы должны упомянуть, что будет работать только с GNU awk из-за многосимвольного RS.
Вы можете попробовать этот GNU sed
sed '/./!d;:A;$bB;N;/\n$/!bA;:B;/string/d' infile
sed предназначен для выполнения s/old/new/ на отдельных входных строках это все. Хотя в нем есть миллион загадочных комбинаций символов для других вещей, все они устарели в середине 1980-х, когда был изобретен awk, и, если они не мазохисты, люди используют их сегодня только для умственных упражнений, а не для реального кода.
$ awk -v RS= -v ORS='\n\n' '!/string/' file
config host
mac '00:a0:00:00:00:00'
option name 'laptop1'
option dns '1'
config host
option name 'laptop3'
mac '00:a0:00:00:00:00'
option dns '1'
.
$ awk -v RS= -v ORS='\n\n' '!/laptop1/' file
config host
option mac '00:a0:00:00:00:00'
option name 'string'
option dns '1'
config host
option name 'laptop3'
mac '00:a0:00:00:00:00'
option dns '1'
Это может сработать для вас (GNU sed):
sed '/config host/{:a;N;/^\s*$/M!ba;/string/d}' file
Соберите строки, начинающиеся с config host, в пустую строку. Если строки содержат string, удалите эти строки, в противном случае распечатайте их.
Я выбрал, исходя из переносимости, но даже трудно сказать, какой из них действительно лучший. Спасибо вам всем! / awk -v RS = -v ORS = '\ n \ n' '! /' $ строка '/' файл