私はほぼ一日中GPT、sed文書、正規表現を扱うのに苦労しています。 Ciscoプレフィックスリスト設定を含むファイルを解析し、指定された正規表現リスト名と一致しないリストを印刷し、そのリストのコンテンツまたは同じリスト名の下にインデントされたコンテンツを無視しようとします。
たとえば、私のファイルは次のようになります(ネットワークの難読化)。
ip prefix-list ispA_in_pref-150
ip prefix-list ispB_in_pref-100
ip prefix-list ispC_out_deny
seq 10 permit 23.1.24.3/24
ip prefix-list ispD_in_pref-50
seq 10 permit 5.2.3.4/24
ip prefix-list ispD_in_pref-100
seq 10 permit 4.18.27.58/24
ip prefix-list ispE_out_deny
seq 10 permit 9.2.3.4/24
seq 20 permit 4.4.4.1/24
ip prefix-list ispF_out_deny
seq 10 permit 2.2.3.4/24
seq 20 permit 28.2.3.1/24
ip prefix-list ispG_out_deny
seq 10 permit 4.2.3.4/24
ip prefix-list ispH_in_pref-150
ip prefix-list ispI_out_deny
seq 10 permit 3.2.3.4/24
私が望むもの:
ip prefix-list ispA_in_pref-150
ip prefix-list ispB_in_pref-100
ip prefix-list ispD_in_pref-50
seq 10 permit 5.2.3.4/24
ip prefix-list ispD_in_pref-100
seq 10 permit 4.18.27.58/24
ip prefix-list ispH_in_pref-150
私が得続けるのは次のような出力です(そしてsedコマンド):
:~$ sed -e '/deny/{:a;N;/\n.*seq.*/!ba;d}' file
ip prefix-list ispA_in_pref-150
ip prefix-list ispB_in_pref-100
ip prefix-list ispD_in_pref-50
seq 10 permit 5.2.3.4/24
ip prefix-list ispD_in_pref-100
seq 10 permit 4.18.27.58/24
seq 20 permit 4.4.4.1/24
seq 20 permit 28.2.3.1/24
ip prefix-list ispH_in_pref-150
まったく異なるリストから2つの異なる「seq 20」行を取得する方法に注意してください。
GPT の場合、次の例が提供されます。
Line 1
Pattern Line
Line 2
This is a line below Line 2
Another line below Line 2
Pattern Line
Line 3
結果は次のとおりです。
:~$ sed -e '/Line 2/{:a;N;/\nPattern.*/!ba;d}' input_file
Line 1
Pattern Line
Line 2
Line 3
私はこれを再現できましたが、ACLファイルを使用しませんでした。
sedにコンテキストを提供するためにバッファを維持することでこれを行う方法があると誓うことができますが、投稿を再配置できないため、実行された他のコマンドがあるかどうかはわかりません。 sedはネットワーク表記の「/」によって混乱を引き起こしますか?もっと良い方法がありますか?
答え1
奇妙な:
$ awk '/deny/ { deny=1; next }
/^ip/ { deny=0; print; next }
!deny' < data
ip prefix-list ispA_in_pref-150
ip prefix-list ispB_in_pref-100
ip prefix-list ispD_in_pref-50
seq 10 permit 5.2.3.4/24
ip prefix-list ispD_in_pref-100
seq 10 permit 4.18.27.58/24
ip prefix-list ispH_in_pref-150
答え2
awkを使用してください。
$ awk '/^ip/{f=/deny/} !f' file
ip prefix-list ispA_in_pref-150
ip prefix-list ispB_in_pref-100
ip prefix-list ispD_in_pref-50
seq 10 permit 5.2.3.4/24
ip prefix-list ispD_in_pref-100
seq 10 permit 4.18.27.58/24
ip prefix-list ispH_in_pref-150
答え3
直面する問題は、シスコのプレフィックスのリストが本質的に階層的であり、正規表現だけではsed
かなり複雑になる可能性があるためです。シングルラインパターンのマッチングと交換に適しています。希望の結果を得るにはawk
。perl
以下を使用するソリューションは次のとおりですawk
。
awk '
/^ip prefix-list/ { # If the line starts with "ip prefix-list"
list_name = $3 # Set list_name to the third field
match(list_name, /^.*\//) # Check if list_name contains a slash
if (RSTART) { # If it does, it's a main list, print it
print
in_main_list = 1
} else { # Otherwise, it's a sub-list, ignore it
in_main_list = 0
}
}
/^ / && in_main_list { # If the line starts with a space (sub-list) and in_main_list is true
next # Skip this line
}
in_main_list { # If we are inside a main list, print the line
print
}
' file
スクリプトは次のことを行いますawk
。
「ip prefix-list」で始まる行に会ったら、リスト名にスラッシュ( "/")が含まれていることを確認してください。その場合、デフォルトのリストとして扱われ、スクリプトはそれを印刷し、
in_main_list
フラグ()をtrueに設定します。行が空白で始まり
in_main_list
trueの場合は、その行をスキップします(サブリスト項目を無視)。true の場合、
in_main_list
行を印刷します。
このスクリプトはサブリスト項目をフィルタリングして目的の出力を提供する必要があります。