Linux

當文件包含多個符號時如何在兩個字元串之間提取

  • March 9, 2019

我一直在嘗試從一個巨大的文件中提取表單數據。我需要一個非常具體的模式,到目前為止我失敗了。

我在日誌中有這個一致的部分:

Machine info and user info blah blah blah [senderID=60, 
ipaddress=/10.1.1.11:8443, serviceIdinList=[13], serviceBitbox=11111, 
servicesList= | BeatController | BeatMaker | WaveShow, client=apache, 

所有的行都是這樣的。

從這一行開始,我需要使它看起來像這樣:

senderID=60, ipaddress=/10.1.1.11:8443, serviceIdinList=[13], 
serviceBitbox=11111, servicesList= | BeatController | BeatMaker | WaveShow,  

*注意,“WaveShow”之後的所有內容都無關緊要,就像“senderID”之前的所有內容一樣

我已經從這裡的文章中嘗試過這個命令,

sed -n '/servicesList=/{s/.*servicesList=//;s/\S*=.*//;p}'

但它只列印出來

servicesList= | BeatController | BeatMaker | WaveShow

我試圖用正則表達式在一些迭代中修改它,用 grep 和 sed 玩過,但沒有進展

如果您要做的是輸出介於 and 之間的所有內容senderID=WaveShow,那麼您需要以下sed命令:

sed -n 's/.*\(senderID=.*WaveShow,\).*/\1/p'

\(這將使用和\)括號擷取這兩個字元串之間的所有內容,並使用\1\2等,如果您有更多擷取)輸出。

請注意,前導.*是“貪婪的”,這意味著如果您senderID=在輸入中有兩次字元串,那麼第一個將被丟棄。如果這不是您想要的,那麼sed就不是正確的工具;perl可以處理這個。然後命令變為:

perl -ne 'print if s/.*?(senderID=.*WaveShow,).*/$1/'

-n意思是“為每一行輸入執行一個循環,並且不要在循環結束時列印該行”。-e指定要在循環內執行的表達式。

更改?後儘可能少地匹配(即非貪婪匹配)。方括號使 perl 對該部分進行分組並擷取它,然後可以將其用作第一次擷取,第二次擷取等。.*``*``$1``$2

然而,這不是在 perl 中執行此操作的最佳方式。這要好得多,因為它不涉及不必要地更改字元串、擷取文本並列印:

perl -ne 'print "$1\n" if /(senderID=.*WaveShow,)/'

在 perl 中可能有更多的方法可以做到這一點,甚至可能更有效。

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