我几乎一整天都在与 GPT、sed 文档和正则表达式作斗争。我试图解析包含思科前缀列表配置的文件,并打印出与给定正则表达式列表名称不匹配的列表,并忽略该列表的内容或同一列表名称下和缩进的内容。
例如,我的文件如下所示(网络混淆):
ip prefix-list ispA_in_pref-150
ip prefix-list ispB_in_pref-100
ip prefix-list ispC_out_deny
seq 10 permit 23.1.24.3/24
ip prefix-list ispD_in_pref-50
seq 10 permit 5.2.3.4/24
ip prefix-list ispD_in_pref-100
seq 10 permit 4.18.27.58/24
ip prefix-list ispE_out_deny
seq 10 permit 9.2.3.4/24
seq 20 permit 4.4.4.1/24
ip prefix-list ispF_out_deny
seq 10 permit 2.2.3.4/24
seq 20 permit 28.2.3.1/24
ip prefix-list ispG_out_deny
seq 10 permit 4.2.3.4/24
ip prefix-list ispH_in_pref-150
ip prefix-list ispI_out_deny
seq 10 permit 3.2.3.4/24
我想要的是:
ip prefix-list ispA_in_pref-150
ip prefix-list ispB_in_pref-100
ip prefix-list ispD_in_pref-50
seq 10 permit 5.2.3.4/24
ip prefix-list ispD_in_pref-100
seq 10 permit 4.18.27.58/24
ip prefix-list ispH_in_pref-150
我不断得到的是这样的输出(加上 sed 命令):
:~$ sed -e '/deny/{:a;N;/\n.*seq.*/!ba;d}' file
ip prefix-list ispA_in_pref-150
ip prefix-list ispB_in_pref-100
ip prefix-list ispD_in_pref-50
seq 10 permit 5.2.3.4/24
ip prefix-list ispD_in_pref-100
seq 10 permit 4.18.27.58/24
seq 20 permit 4.4.4.1/24
seq 20 permit 28.2.3.1/24
ip prefix-list ispH_in_pref-150
请注意它如何从完全不同的列表中获取其他 2 个“seq 20”行。
对于 GPT,它给出了这样的例子:
Line 1
Pattern Line
Line 2
This is a line below Line 2
Another line below Line 2
Pattern Line
Line 3
结果如下:
:~$ sed -e '/Line 2/{:a;N;/\nPattern.*/!ba;d}' input_file
Line 1
Pattern Line
Line 2
Line 3
我已经能够重现这一点,但不能使用 ACL 文件。
我可以发誓有一种方法可以通过保留缓冲区来做到这一点,从而为 sed 提供一些上下文,但我无法重新定位该帖子,所以我也不知道是否还运行了其他命令。 sed 是否会因为网络符号中的“/”而感到困惑?有一个更好的方法吗?
答案1
awk:
$ awk '/deny/ { deny=1; next }
/^ip/ { deny=0; print; next }
!deny' < data
ip prefix-list ispA_in_pref-150
ip prefix-list ispB_in_pref-100
ip prefix-list ispD_in_pref-50
seq 10 permit 5.2.3.4/24
ip prefix-list ispD_in_pref-100
seq 10 permit 4.18.27.58/24
ip prefix-list ispH_in_pref-150
答案2
使用任何 awk:
$ awk '/^ip/{f=/deny/} !f' file
ip prefix-list ispA_in_pref-150
ip prefix-list ispB_in_pref-100
ip prefix-list ispD_in_pref-50
seq 10 permit 5.2.3.4/24
ip prefix-list ispD_in_pref-100
seq 10 permit 4.18.27.58/24
ip prefix-list ispH_in_pref-150
答案3
您面临的挑战是因为 Cisco 前缀列表本质上是分层的,并且单独使用正则表达式sed
可能会变得相当复杂。它更适合单行模式匹配和替换。为了达到您想要的结果,您可能需要更强大的文本处理工具,例如awk
或perl
。这是一个使用以下解决方案awk
:
awk '
/^ip prefix-list/ { # If the line starts with "ip prefix-list"
list_name = $3 # Set list_name to the third field
match(list_name, /^.*\//) # Check if list_name contains a slash
if (RSTART) { # If it does, it's a main list, print it
print
in_main_list = 1
} else { # Otherwise, it's a sub-list, ignore it
in_main_list = 0
}
}
/^ / && in_main_list { # If the line starts with a space (sub-list) and in_main_list is true
next # Skip this line
}
in_main_list { # If we are inside a main list, print the line
print
}
' file
该脚本的作用如下awk
:
当它遇到以“ip prefix-list”开头的行时,它会检查列表名称是否包含斜杠(“/”)。如果是,则将其视为主列表,脚本将打印它并将标志 (
in_main_list
) 设置为 true。如果该行以空格开头并且
in_main_list
为 true,则它会跳过该行(忽略子列表条目)。如果
in_main_list
为 true,则打印该行。
该脚本应该为您提供所需的输出,过滤掉子列表条目。