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
。