特定の基準を使用して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

これは行を!レコード区切り文字として扱い、一度に 1 つのインタフェースに関連する「段落」全体を読み込みます。レコードは行ごとに「フィールド」に分割されます。つまり、行は「フィールド」と解釈されます。

その後、プログラムはすべてのフィールドを繰り返し、パターンが見つかると次のレコードに移動します。キーワードが見つからず、段落に少なくとも1行(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}

修正する

アップデートで公開された2番目の例では別のファイル形式が使用されているため(区切り記号が変更され、除外されている可能性があるため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

関連情報