Command-Line

grep 正則表達式解決方案(貪心不工作)

  • September 20, 2016

我在 data.txt 文件中有以下文本

:MENU1
0. public
1. admin
2. webmail

:SYNTAX
! opt1, ... :

:ERROR1
Error #1, blah... blah.. blah...
Please do ...

:ERROR2
Error #2 ...

我想使用正則表達式(PERL 語法)將部分從:MENU1下一個 first中提取出來:,但從結果中刪除MENU1和最後一個:

一直在嘗試幾個正則表達式,但在我得到的最接近的解決方案中,我無法使用“貪婪”選項,也不能丟棄最後一個“:”

grep -Poz "^:MENU1\K[\w\W]*:"

這適用於 grep …

但將所有文本帶到最後一個“:” …

我只想要直到下一個第一個“:”之後:MENU1

0. public
1. admin
2. webmail
 

(注意最後的空行)

該模式*:將匹配所有內容,直到最後一個:. 要停在:你需要的下一個*?:。例如:

% grep -Poz '^:MENU1\K[\w\W]*?:' data.txt 

0. public
1. admin
2. webmail

:

您可以通過在\K. 例如:

% grep -Poz '^:MENU1\n\K[\w\W]*?:' data.txt 
0. public
1. admin
2. webmail

:

要吃空行,:您可以匹配並丟棄該文本。例如:

% grep -Poz '^:MENU1\n\K[\w\W]*?(?=\n+:)' data.txt 
0. public
1. admin
2. webmail

接下來,我們可以簡化您的角色類,以匹配除以下內容之外的任何內容:

% grep -Poz '^:MENU1\n\K[^:]*?(?=\n+:)' data.txt 
0. public
1. admin
2. webmail

最後我們可以重寫匹配的初始部分:

% grep -Poz '(?<=:MENU1\n)[^:]*?(?=\n+:)' data.txt 
0. public
1. admin
2. webmail

這與@terdon 提出的類似,但無需再次呼叫 grep 即可處理空行。

這個最終的正則表達式使用了環視斷言。The(?<=pattern)是一個look-behind斷言,可讓您匹配pattern但不包含它作為輸出的一部分。這(?=pattern)是一個look-ahead斷言,讓我們匹配尾隨模式而不將其包含在輸出中。

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