这是 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
。