有没有办法格式化以下输出,以便仅打印第 1 行和声明“规则”名称的相应行?根据配置的不同,“规则”行可能会有所不同。可以是第 4、5、8 行等。如图所示,规则名称位于括号中。最好是第一行和规则行一起出现,如下面的“所需输出”示例中所示。
命令:show virtual server
原始输出:
adc virtual name_of_virtual_server {
output
destination 10.201.111.101:80
ip-protocol tcp
mask 255.255.255.255
pool test
profiles {
test {
context clientside
}
test { }
test data {
context serverside
}
}
rules {
Exchange__all_services2.dat/Exchange__all_services2_rule7
}
source 0.0.0.0/0
source-address-translation {
pool data_pool
type snat
}
vs-index 13
}
期望的输出:
name_of_virtual_server
rules {
Exchange__all_services2.dat/Exchange__all_services2_rule7
或者 - 更好 - 在条目之间有一个空行:
Name: name_of_virtual_server
Rule: Exchange__all_services2.dat/Exchange__all_services2_rule7
这可以用 sed 或 awk 实现吗?请记住,如果重要的话,一个配置文件中可能有数百个虚拟服务器配置。
答案1
这是 perl 中的一种方法:
perl -ne 'if (/^adc\s+\w+\s+(\w+)/) { print "Name: $1\n" }
elsif (/^\s*rules\s*{/) { $inrule = 1; }
elsif (/}/) { $inrule = 0; }
elsif (/^\s*(\S*)/) { print "Rule: $1\n" if $inrule; }'
它会遍历文件的每一行,Name:
当它看到一行时打印一行adc
,然后在识别
rules {}
块方面进行了一次糟糕的尝试,将其中的每一行打印为Rule:
.
为您的输入格式使用适当的解析器会更加健壮;如果布局与您的问题不完全一样,这一行将会中断。
答案2
如果有适合该文件的文件格式的解析器,则应该使用它。如果缺少这一点,这里有一个适用于您的示例输入的解决方案:
$ awk '/^adc/{print "name:",$3} /^[[:space:]]*rules/{getline;print "rule:",$1}' file
name: name_of_virtual_server
rule: Exchange__all_services2.dat/Exchange__all_services2_rule7
怎么运行的
/^adc/{print "name:",$3}
对于以 开头的任何行
adc
,打印出name:
该行的第三项。/^[[:space:]]*rules/{getline;print "rule:",$1}
对于任何以空格(可选)开头,后跟 的行
rules
,这将打印出后续行中的第一项。