查找特殊字符之间的模式

查找特殊字符之间的模式

我需要一个 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-eservice_descriptionMulti 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.txtinputfile.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 的slurped 数据的内部表示,请删除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

相关内容