我需要一个 Sed/awk 命令来打印特殊字符之间的数据,前提是模式匹配应出现在特殊字符 ({ & }) 之间
我有一个文件,其中包含
define service {
host_name dns_vips
service_description Multi Lookup
use standard_service_template
active_checks_enabled 1
passive_checks_enabled 1
notifications_enabled 1
contact_groups mailgrp
max_check_attempts 3
normal_check_interval 5
retry_check_interval 1
notification_interval 10
check_period 24x7
notification_period 24x7
notification_options w,r,c
}
define service {
host_name dns_vips1
service_description Multi Lookup 2
use standard_service_template
active_checks_enabled 1
passive_checks_enabled 1
notifications_enabled 1
contact_groups mailgrp1
max_check_attempts 3
normal_check_interval 5
retry_check_interval 1
notification_interval 10
check_period 24x7
notification_period 24x7
notification_options w,r,c
}
我需要服务描述与多重查找匹配期间{
和期间的数据}
答案1
sed '
/{/{ #starts next code block if line include «{»
:1 #set mark point
/}/!{ #execute if pattern (collected lines) do not include «}»
N #add next line to the pattern space
b1 #return to marked point
} #end of second (inner) block of code
} #end of first block of code
/Multi Lookup/p #prints pattern (collected lines) if it has «Multi Lookup»
d #clean pattern (start from the beginning)
' file
答案2
如果我理解正确的话,你的所有数据都在里面{ }
,你想打印那些service_description
匹配的记录Multi Lookup
。如果是这样,你可以使用一个很酷的perl
技巧。
Perl 有一个“段落模式”,其中记录(行)由空行定义。因此,如果您在 every 之后添加一个换行符}
,您可以简单地执行以下操作:
sed 's/}/}\n/' file | perl -00ne '/service_description\s*Multi Lookup/ && print'
每个后面都会sed
添加一个. Perl将打开段落模式并使其读取每个输入行(此处,行表示段落)并应用给定的脚本。结果是打印匹配的记录。\n
}
-00
-ne
-e
service_description
Multi Lookup
$/
或者,您可以在脚本本身中设置 perl 的记录分隔符(定义“行”的内容)、变量,并避免该sed
步骤
perl -ne 'BEGIN{$/="}\n"}/service_description\s*Multi Lookup/ && print' file
答案3
只是为了好玩,我尝试将其作为vim
一句台词来做。 (谁听说过这样的事,对吧?)
vim -c 'g/service_description\s\+Multi Lookup\s\+$/?{?+,/}/-w! >> outputfile.txt' -c 'q!' inputfile.txt
作用:查找包含service_description
[whitespace] Multi Lookup
[whitespace, end of line] 的每一行,并输出每次匹配的从前{
到后的所有行,不包括包含和字符的}
行,并将输出行写入。然后它退出而不修改.{
}
outputfile.txt
inputfile.txt
我不知道你是否愿意Multi Lookup 2
匹配;如果是这样,请删除\s\+$
后面的Multi Lookup
.
如果您还想包含带有大括号的行,请删除+
后面的?{?
和-
后面的/}/
。
可能有点矫枉过正,因为你可以只使用sed
,但这对我来说是很好的练习。 :)
答案4
使用乐(以前称为 Perl_6)
~$ raku -e '.put if /service_description \h+ Multi \h Lookup/ for slurp.comb(/^^ define \h service \h \{ <-[ } ]>* \} $$ /);' file
#OR (more simply)
~$ raku -e '.put if /DESIRED_MATCH/ for slurp.comb( / ^^START <-[ END_char ]>* END$$ /);'
上面是用 Raku(Perl 编程语言家族的成员)编写的答案。从右到左读取代码,Rakuslurp
一次性将文件读入内存,并且comb
可以被认为是相反的,split
因为它选择用于匹配文本块(而不是销毁相同的文本块)。这种方法使得选择对所需文本块之间的无关字符不敏感。
^^
行开始和行$$
结束断言用于提供特异性,并且块内部字符使用 定义<-[ } ]>*
,这是一个负字符类,包含(零个或多个)除}
右大括号之外的任何字符。comb
使用 迭代 ed 元素,for
找到if
所需的匹配项(\h
代表水平空白),该元素就出来了put
。
给定OP的输入文件(更改第二个卷曲块以提供负控制),我们得到以下输出:
输入示例:
define service {
host_name dns_vips
service_description Multi Lookup
use standard_service_template
active_checks_enabled 1
passive_checks_enabled 1
notifications_enabled 1
contact_groups mailgrp
max_check_attempts 3
normal_check_interval 5
retry_check_interval 1
notification_interval 10
check_period 24x7
notification_period 24x7
notification_options w,r,c
}
define service {
host_name dns_vips1
service_description Single Lookup
use standard_service_template
active_checks_enabled 1
passive_checks_enabled 1
notifications_enabled 1
contact_groups mailgrp1
max_check_attempts 3
normal_check_interval 5
retry_check_interval 1
notification_interval 10
check_period 24x7
notification_period 24x7
notification_options w,r,c
}
示例输出:
define service {
host_name dns_vips
service_description Multi Lookup
use standard_service_template
active_checks_enabled 1
passive_checks_enabled 1
notifications_enabled 1
contact_groups mailgrp
max_check_attempts 3
normal_check_interval 5
retry_check_interval 1
notification_interval 10
check_period 24x7
notification_period 24x7
notification_options w,r,c
}
为了简化 所使用的搜索正则表达式comb
,我们可以使用 Raku 的~
波浪号表示法来查找匹配的分隔符(花括号、方括号、括号等),从而为我们提供[ \{ ~ \} <-[ } ]>* ]
替代。另外,如果我们想查看 Raku 的slurp
ed 数据的内部表示,请删除if
条件并使用.raku.put
,如下所示:
~$ raku -e '.raku.put for slurp.comb(/^^ define \h service \h [ \{ ~ \} <-[ } ]>* ] $$/);' file
"define service \{\nhost_name dns_vips\nservice_description Multi Lookup \nuse standard_service_template\nactive_checks_enabled 1\npassive_checks_enabled 1\nnotifications_enabled 1\ncontact_groups mailgrp\nmax_check_attempts 3\nnormal_check_interval 5\nretry_check_interval 1\nnotification_interval 10\ncheck_period 24x7\nnotification_period 24x7\nnotification_options w,r,c\n}"
"define service \{\nhost_name dns_vips1\nservice_description Single Lookup\nuse standard_service_template\nactive_checks_enabled 1\npassive_checks_enabled 1\nnotifications_enabled 1\ncontact_groups mailgrp1\nmax_check_attempts 3\nnormal_check_interval 5\nretry_check_interval 1\nnotification_interval 10\ncheck_period 24x7\nnotification_period 24x7\nnotification_options w,r,c\n}"
如果slurp
一次全部导入文件有问题,您可以尝试lines.join("\n")
一下,这可能提高记忆效率。此外,这个答案可以使用 Raku 的哈希数据结构重写%
,从而使对多个不同键值对的分析也更加有效。
https://docs.raku.org/language/regexes#Tilde_for_nesting_structs
https://docs.raku.org
https://raku.org