如何使用特定条件 grep Cisco IOS 配置中的某些接口块?

如何使用特定条件 grep Cisco IOS 配置中的某些接口块?

这是 Cisco IOS 中网络接口配置的示例。我们将其命名为cisco.txt.

!
interface FastEthernet0/1
 shutdown
!
interface FastEthernet0/2
 switchport access vlan 20
!
interface FastEthernet0/3
 switchport mode access
!
interface FastEthernet0/4
!
interface FastEthernet0/5
 switchport access vlan 50
 switchport mode access
!

我想做的是 grep 没有以下关键字的接口:

shutdown|switchport access vlan \d+|switchport mode access

但是,我现在真的不知道该怎么做。我现在唯一能想到的就是 grep 那些匹配这样的模式。

grep -P 'interface|shutdown|switchport access vlan \d+|switchport mode access' cisco.txt

例如

$ grep -P 'interface|shutdown|switchport access vlan \d+|switchport mode access' cisco.txt
interface FastEthernet0/1
 shutdown
interface FastEthernet0/2
 switchport access vlan 20
interface FastEthernet0/3
 switchport mode access
interface FastEthernet0/4
interface FastEthernet0/5
 switchport access vlan 50
 switchport mode access
$ 

我还尝试-v, --invert-match选择不匹配的行,但我得到的唯一输出就是这个。

$ grep -vP 'interface|shutdown|switchport access vlan \d+|switchport mode access' cisco.txt
!
!
!
!
!
!
$ 

我希望仅根据上面的标准获得以下输出。

interface FastEthernet0/4

另外,如果grep这不是合适的工具,请告诉我替代方案。

更新

感谢@AdminBee,它适用于前面的示例。但是,当我尝试使用不同的配置时,我没有得到类似的结果。

awk我稍微改变了脚本的标准。

awk 'BEGIN{RS="!\n";FS=OFS="\n"} {for (i=i;i<=NF;i++) {if ($i~/^ *(switchport mode trunk|switchport mode access|switchport access vlan ) *$/) next}} NF' cisco2.txt

如果找到任何这些条件,则不打印界面,因此它只会打印interface GigabitEthernet 1/3

switchport mode trunk|switchport mode access|switchport access vlan

新的配置文件

$ cat cisco2.txt 
hostname ExampleSwitch

interface GigabitEthernet 1/1
 switchport mode trunk
 shutdown

interface GigabitEthernet 1/2
 switchport mode access
 switchport access vlan 20
 switchport nonegotiate
 no cdp enable

interface GigabitEthernet 1/3
 no switchport
 ip address 192.0.2.1 255.255.255.0
$ 

输出(不显示任何内容)

$ awk 'BEGIN{RS="!\n";FS=OFS="\n"} {for (i=i;i<=NF;i++) {if ($i~/^ *(switchport mode trunk|switchport mode access|switchport access vlan ) *$/) next}} NF' cisco2.txt
$ 

所需输出

interface GigabitEthernet 1/3

或者

interface GigabitEthernet 1/3
 no switchport
 ip address 192.0.2.1 255.255.255.0

答案1

您可以用于awk以下目的:

awk 'BEGIN{RS="!\n";FS=OFS="\n"}
     {for (i=i;i<=NF;i++) {if ($i~/^ *(shutdown|switchport access vlan [[:digit:]]+|switchport mode access) *$/) next}}
     NF' cisco.txt

这会将行视为!记录分隔符,并一次读取与一个界面关联的整个“段落”。记录将按行分成“字段”,即一行被解释为一个“字段”。

然后,程序将迭代所有字段,如果找到任何一个模式,则跳到下一条记录执行。如果没有找到任何关键字,并且段落中至少有一行(NF非零;这是为了防止输出空记录),则打印该段落。对于你的例子:

user@host~$ awk 'BEGIN{RS="!\n";FS=OFS="\n"} {for (i=i;i<=NF;i++) {if ($i~/^ *(shutdown|switchport access vlan [[:digit:]]+|switchport mode access) *$/) next}} NF' cisco.txt
interface FastEthernet0/4

如果您只想确保只打印包含该interface语句的行,NF请将

NF {print $1}

甚至更有选择性

NF && $1~/interface/ {print $1}

更新

您在更新中发布的第二个示例使用不同的文件格式(分隔符现在已更改,并且可以有除 之外的部分interface),因此上面提出的解决方案在那里不起作用。相反,请尝试以下操作:

awk 'BEGIN{RS="";FS=OFS="\n"}
     {for (i=i;i<=NF;i++) {if ($i~/^ *(switchport mode trunk|switchport mode access|switchport access vlan ) *$/) next}}
     NF && $1~/interface/ {print $1}' cisco2.txt

这会将记录分隔符设置为空行,但其他方面的工作方式与上面相同。但是,仅当该部分以以下开头时才会生成输出interface(以排除该hostname行,例如),并且将(再次)仅打印包含该语句的第一行interface

相关内容