Linux
當文件包含多個符號時如何在兩個字元串之間提取
我一直在嘗試從一個巨大的文件中提取表單數據。我需要一個非常具體的模式,到目前為止我失敗了。
我在日誌中有這個一致的部分:
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 中可能有更多的方法可以做到這一點,甚至可能更有效。