第一次来电...长期读者。
以下是我正在使用的输入示例。
.
.
.
exit
exit
set vsys "dr-site"
set vsys-id 2
set vrouter "dr-site-vr"
unset auto-route-export
exit
set service "service1"
set service "service2"
set zone id 101 "Trust1"
set zone id 201 "Untrust1"
set zone id 301 "DMZ1"
set interface "ethernet3/1.3"
set interface "ethernet3/1.4"
set interface "ethernet3/1.6"
set route 0.0.0.0/0
set address "Untrust1"
set address "Trust1"
set address "DMZ1"
set group address "Untrust1"
set group address "Trust1"
set group address "DMZ1"
set group service
set policy id 100
exit
set policy id 200
exit
set policy id 300
exit
set policy id 400
exit
exit
set vsys "datacenter"
set vsys-id 1
set vrouter "datacenter-vr"
unset auto-route-export
exit
set service "service1"
set service "service2"
set zone id 100 "Trust"
set zone id 200 "Untrust"
set zone id 300 "DMZ"
set interface "ethernet3/1.5"
set interface "ethernet3/1.2"
set interface "ethernet3/1.1"
set route 0.0.0.0/0
set address "Untrust"
set address "Trust"
set address "DMZ"
set group address "Untrust"
set group address "Trust"
set group address "DMZ"
set group service
set policy id 100
exit
set policy id 200
exit
set policy id 300
exit
set policy id 400
exit
exit
set vsys "other"
.
.
.
我需要在set vsys "datacenter"
(例如)开始我的范围,并在看到(2)连续exit
时停止。
通常,我只是:
gsed -n '/set vsys "datacenter"/,/exit/p; file
但我需要模式#2来捕获(2)连续退出:
gsed -n '/set vsys "datacenter"/,/exit\nexit/p; file
因此我的范围匹配具有范围#2的多线模式。
我尝试过使用sed N命令,但我没有做正确的事情。我还将使用此sed命令根据需要解析vsys部分,这些部分始终以(2)连续exit
结束。
根据要求,预期输出应如下所示:
set vsys "datacenter"
set vsys-id 1
set vrouter "datacenter-vr"
unset auto-route-export
exit
set service "service1"
set service "service2"
set zone id 100 "Trust"
set zone id 200 "Untrust"
set zone id 300 "DMZ"
set interface "ethernet3/1.5"
set interface "ethernet3/1.2"
set interface "ethernet3/1.1"
set route 0.0.0.0/0
set address "Untrust"
set address "Trust"
set address "DMZ"
set group address "Untrust"
set group address "Trust"
set group address "DMZ"
set group service
set policy id 100
exit
set policy id 200
exit
set policy id 300
exit
set policy id 400
exit
exit
答案 0 :(得分:1)
使用GNU sed:
sed -r 'H;1h;$!d;x;s/.*(set vsys "datacenter".*exit\nexit).*/\1/' file
对于BSD sed,请尝试将-r
替换为-E
。
H;1h;$!d;x;
这是用于立即读取整个文件的sed习语。如果文件很大,请使用不同的解决方案,例如下面的awk解决方案。
s/.*(set vsys "datacenter".*exit\nexit).*/\1/
这会提取我们想要的部分。
awk '/set vsys "datacenter"/{f=1;} f{print;} /exit/ && last {exit;} {last=0;} f && /exit/{last=1;}' file
/set vsys "datacenter"/{f=1;}
当我们看到起始行时,将标志f
设置为true(1)。
f{print}
如果标记f
为真,则打印行
/exit/ && last {exit;}
如果此行包含exit
且上一行也包含exit
,那么我们就完成了,我们告诉awk exit
。
{last=0}
将last设置为false(0)。
f && /exit/{last=1}
准备下一行。如果标记f
为真且此行包含exit
,则将last设置为true(1)。
#!/usr/bin/python3
f = False
last = False
with open('file', 'r') as fhandle:
for line in fhandle:
if 'set vsys "datacenter"' in line:
f = True
if f:
print(line, end="")
if last and 'exit' in line:
break
last = False
if f and 'exit' in line:
last = True
这里的逻辑基本上与awk解决方案相同。
答案 1 :(得分:1)
未经测试,因为您没有提供预期的输出,但您需要这样的内容:
awk '
/set vsys "datacenter"/{ f=1; rec=prev="" }
f {
rec=rec $0 ORS
if ( /exit/ && (prev==$0) ) {
printf "%s", rec
f=0
}
prev = $0
}
' file
答案 2 :(得分:0)
这可能适合你(GNU sed):
sed '/set vsys "datacenter"/!d;:a;N;/exit\s*\nexit\s*$/!ba' file
如果某行不包含所需的字符串,请将其删除。如果是,请附加以下行并检查双exit
条件,如果未找到,则继续追加行,直到满足条件。打印出图案空间中的线条。