Text-Processing

文件中的匹配行,按順序排列 2 個字元串列表

  • April 29, 2022

我正在嘗試匹配文件中的訪問列表行,其中某些環境(列表 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

引用自:https://unix.stackexchange.com/questions/700419