특정 기준을 사용하여 Cisco IOS 구성에서 특정 인터페이스 블록을 찾는 방법은 무엇입니까?

특정 기준을 사용하여 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 -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

이는 행을 !레코드 구분 기호로 처리하고 한 번에 하나의 인터페이스와 관련된 전체 "단락"을 읽습니다. 레코드는 행별로 "필드"로 나뉩니다. 즉, 행은 "필드"로 해석됩니다.

그런 다음 프로그램은 모든 필드를 반복하고 패턴이 발견되면 다음 레코드로 이동합니다. 키워드가 발견되지 않고 단락에 최소한 한 줄( NF0이 아님, 빈 레코드가 출력되는 것을 방지하기 위한 것임)이 있는 경우 단락이 인쇄됩니다. 귀하의 예를 들어:

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.

관련 정보