2017-08-14 58 views
0

我有這個示例文件:獲取從文本的多個匹配在大括號

authoritative; 

subnet x.x.x.x netmask x.x.x.x { 
    range x.x.x.x x.x.x.x; 
    deny unknown-clients; 
    default-lease-time 86400; 
    max-lease-time 86400; 
    option domain-name "bla"; 
    option domain-name-servers x.x.x.x; 
    option broadcast-address x.x.x.x; 
    option subnet-mask x.x.x.x; 
    option routers x.x.x.x; 

    host host1 { 
     hardware ethernet 00:e1:4c:68:00:53; 
     fixed-address 1.1.1.1; 
    } 

    host host2 { 
     hardware ethernet 01:e2:4d:69:01:54; 
     fixed-address 2.2.2.2; 
    } 

    host host3 { 
     hardware ethernet 02:e3:4e:70:02:55; 
     fixed-address 3.3.3.3; 
    } 

    host host4 { 
     hardware ethernet 03:e4:4f:71:03:56; 
     fixed-address 4.4.4.4; 
    } 

    host host5 { 
     hardware ethernet 04:e5:5f:72:04:57; 
     fixed-address 5.5.5.5; 
    } 
} 

現在,我試圖從主機X塊中提取的MAC地址和IP地址的部分。當我使用這個文件結構(包括newLines)時,它根本不匹配......這是我稍後會解決的問題。 但現在我很難得到所有的比賽。 這是我到目前爲止:Link to MyRegex 正如你可以看到那裏,$ 1和$ 2包含最後的MAC/IP地址條目。 但是,如何獲得樣本文件中所有條目的匹配? 我敢肯定我錯過了一些必不可少的東西......

非常感謝!

+1

什麼語言/工具? – Toto

+0

正如我想簡單瞭解機制,我正在使用此在線工具:http://regexr.com/。最後,我會嘗試將結果與bash腳本工具(如grep/awk/sed)結合起來。但現在我試圖瞭解如何使用正則表達式來準備比賽 - 如果這是可能的話 – user2549803

+0

謝謝,但正如我已經提到的,我希望這種模式只能在主機塊內匹配 – user2549803

回答

1
host.*?\{\s*hardware ethernet\s+(?:((?:[0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2});\s*fixed-address\s+((?:\d{1,3}.){3}\d{1,3}));\s*\} 

Tested here


說明

\s*\}\s*\}你是一個匹配右括號的方式結束了太多。

[0-255]轉換爲0和2或5之間的任何數字。不是你想要的。在這裏使用\d{1,3}更容易。

\sfixed-address您需要\s*fixed-address此處,因爲您可能在fixed-address之前有幾個空格。

+0

哇!非常感謝你的解釋。正是我想要的。 – user2549803

+0

我還有一個問題:爲什麼此解決方案不適用於示例文件的精簡版本?請查看[this](https:// regex101。com/r/cjuygq/1) 非常感謝 – user2549803

+0

您可能應該刪除正則表達式開頭處的'。*'。 – pchaigno

1

哇你的正則表達式看起來過於簡單。一個simplier是:

hardware ethernet ([0-9a-f:]+); fixed-address ([0-9\.]+);

它的所有IP地址和MAC地址相匹配。 RegExr

+0

你是完全正確的。但是,如果由於某種原因,這個組合被寫在主機x代碼塊之外,它也會與之匹配。這就是爲什麼我想確保匹配僅在主機塊上下文中發生的原因。 再次感謝! – user2549803

1

你可以明確地寫出來的部分字符串,使其更容易捕捉比你目前擁有的一個:

(hardware ethernet [\da-f:]+;) (fixed-address [\d\.]+;) 

這種方式,你有兩個拍攝組,這樣就可以輕鬆搞定的MAC地址和IP地址。

1

既然你提到使用awk最終在這裏是一個工作的awk:

awk '/^[ \t]*host /{hostblock=1; next} hostblock && /}/{hostblock=0} !hostblock{next} 
    {gsub(/;/, "", $NF)} /hardware ethernet/{mac[++i]=$NF} /fixed-address/{ip[++j]=$NF} 
END{for (k=1; k<i; k++) print mac[k], ip[k]}' file 

00:e1:4c:68:00:53 1.1.1.1 
01:e2:4d:69:01:54 2.2.2.2 
02:e3:4e:70:02:55 3.3.3.3 
03:e4:4f:71:03:56 4.4.4.4 
+0

謝謝,sed解決方案看起來像[this](https://stackoverflow.com/questions/45586363/parse-blocks-in-curly-brackets) – user2549803

+0

對不起,但'sed'不應該這樣做處理。這就是'awk'的作用,即逐行處理文本文件。 – anubhava