这是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发布于 2021-01-06 15:33:05
您可以将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语句的第一行时,输出才会产生。
https://unix.stackexchange.com/questions/627857
复制相似问题