Text-Processing
文件中的匹配行,按順序排列 2 個字元串列表
我正在嘗試匹配文件中的訪問列表行,其中某些環境(列表 A)是目標,而其他環境(列表 B)是源。反之亦然。
這是在 Ubuntu 伺服器上。
問題是這些列表都在大約 15 行左右,這使得組合相當多,而且 grep 命令很長。正在搜尋的文件總共約為 3000 行。
我知道我可以通過 將文件中的行與文件中的行進行匹配
grep -f
,但是我無法找到滿足我的特定搜尋要求的解決方案,我從 2 個列表中搜尋,並且順序很重要。我想要做的範例(括號是有意的,因為我在一個文件中搜尋,其中每行都附加了相關環境的 IP 地址):
清單 A 內容:
(One) Two Three
清單 B 內容:
(Four) (Five) (Six)
正在搜尋的文件:
access-list acl-name line 1 extended permit tcp host 1.2.3.4 (One) host 5.6.7.8 Two eq ssh access-list acl-name line 1 extended permit tcp host 1.2.3.4 (One) host 5.6.7.8 (Four) eq ssh access-list acl-name line 1 extended permit tcp host 1.2.3.4 (Four) host 5.6.7.8 Three eq ssh access-list acl-name line 1 extended permit tcp host 1.2.3.4 (Six) host 5.6.7.8 (One) eq ssh access-list acl-name line 1 extended permit tcp host 1.2.3.4 (Five) host 5.6.7.8 (Five) eq ssh
所需的輸出(列表 A 作為目標):
access-list acl-name line 1 extended permit tcp host 1.2.3.4 (Six) host 5.6.7.8 (One) eq ssh access-list acl-name line 1 extended permit tcp host 1.2.3.4 (Four) host 5.6.7.8 Three eq ssh
所需的輸出(列表 B 作為目標):
access-list acl-name line 1 extended permit tcp host 1.2.3.4 (One) host 5.6.7.8 (Four) eq ssh
我對 Ubuntu 甚至 python 腳本上可用的任何命令持開放態度。
現在,我的 grep 搜尋看起來像這樣(用於匹配列表 B 是目標的行,列表 A 是源)
grep -iE '\(One\).*\(Four\)|Two.*\(Four\)|Three.*\(Four\)|\(One\).*\(Five\) and so on... '
感謝您提供任何幫助,因此我希望可以將目前腳本從 15000 個字元中減少 :)
假設您有可用的 GNU Awk(用於
FPAT
內部變數),以下程序應該可以工作:awk 'BEGIN{FPAT="host ([[:digit:]]+.){3}[[:digit:]]+ [^ ]+"} t=="src"{src[$0];next} t=="dst"{dest[$0];next} {split($1,a,/ /);lsrc=a[3]; split($2,a,/ /);ldst=a[3]} (lsrc in src && ldst in dest)' t="src" listA t="dst" listB t="" access
該程序將被呼叫並處理三個文件,其中對於每個處理執行,一個
awk
變數t
被設置為不同的值,以允許辨識哪個文件被處理。
- 如果
t
設置為src
,則程序假定這是“源”列表並將行內容讀入關聯數組src
(但僅填充數組索引,實際上並未為該條目分配任何值)。然後處理立即跳到文件的下一行。請注意,必須沒有前導或尾隨空格,否則它們將包含在模式匹配中。此外,稍後的匹配將假定這些行僅包含一個連續的字元串,沒有內部空格。- 如果
t
設置為dst
,則程序假定這是“目標”列表,並將類似地在數組中註冊所有行內容dest
。如果
t
有任何其他值,則程序假定它在“主”訪問列表中並執行實際匹配。
- 在這裡,
FPAT
在該部分中設置的內部變數BEGIN
開始發揮作用。它將把匹配模式 " 的所有部分視為一個“欄位”host
,後跟一個 IPv4 地址(僅執行基本的形式檢查),然後是一個連續的字元串,每個字元串由一個空格分隔。- 第一個這樣的欄位包含“源”部分。它將在空格處拆分為一個數組
a
,第三個數組條目(“環境”部分)儲存在局部變數lsrc
中。- 第二個這樣的欄位將被類似地處理,“環境”部分儲存在局部變數
ldst
中。- 規則塊之外是布爾條件,它將確定是否列印該行。
lsrc
如果包含在數組的索引中並且src
包含ldst
在數組的索引中,則列印該行dest
。結果,使用
listA
作為第一個文件和listB
作為第二個文件將是:> awk ' ... ' t="src" listA t="dst" listB t="" access access-list acl-name line 1 extended permit tcp host 1.2.3.4 (One) host 5.6.7.8 (Four) eq ssh
在相反的情況下,
listB
用作第一個文件和listA
第二個文件:> awk ' ... ' t="src" listB t="dst" listA t="" access access-list acl-name line 1 extended permit tcp host 1.2.3.4 (Four) host 5.6.7.8 Three eq ssh access-list acl-name line 1 extended permit tcp host 1.2.3.4 (Six) host 5.6.7.8 (One) eq ssh