2013-03-28 66 views
1

我想從我的日誌文件中提取<到下一個使用正則表達式提取子字符串

$>cat messages.log 
2013-03-24 19:32:37.231 <F280 [192.168.178.22]:5000 -- Unknown>, Msg:[Test1] 
2013-03-24 19:32:37.547 <F281 [192.168.178.22]:5000 -- Unknown>, Msg:[Test2 
Test3 
Test4] 
2013-03-24 19:32:38.833 <F280 [192.168.178.22]:5000 -- Unknown>, Msg:[Test5] 
2013-03-24 19:32:42.222 <F281 [192.168.178.22]:5000 -- Unknown>, Msg:[Test6] 
$>sed 's/.*\<\(.*\) \[.*/\1|/g' messages.log 
F280| 
F281| 
Test3 
Test4] 
F280| 
F281| 

我幾乎得到了我想要的,除了換行符的輸出。所以我想得到以下結果:

F280|F281|F280|F281 

正則表達式是怎樣的?

回答

2

我不會創建一個不可讀的正則表達式要做到這一點我會使用awk這裏:

$ awk -F'[< ]' '/^[0-9]+/{s?s=s"|"$4:s=s$4}END{print s}' file 
F280|F281|F280|F281 
+0

到目前爲止,它改善了輸出效果,效果更好,但如果將其應用於整個日誌文件,還會打印更多不需要的值。我對awk並不熟悉,但可能您有一個想法如何解決此消息:「Msg:[Test5 \ n AAA/BBB CCC DDD \ n EEE FFF]」=>這會導致不知怎的,「CCC」! – janr 2013-03-28 12:43:58

+1

那麼你可以過濾什麼?你想要什麼線是獨特的?如果他們以'2013'開頭'awk -F'[<]''/^2013/{s?s = s「|」$ 4:s = s $ 4} END {print s}'file'就足夠了? – 2013-03-28 13:15:37

+0

是的,它做到了,但我將「2013」​​更改爲「[0-9] +」!爲什麼「[0-9] {4}」不能用awk工作? – janr 2013-03-28 14:03:30

1

試試這個:

 
sed -n '/</{s/^.*<\([^ ]\+\) .*$/\1|/g;H;${x;s/\n//g;s/|$//;p}}' messages.log 
0

嘗試類似的東西(你會嵌套組),或在正則表達式打開多選項:

(^.+<(\w+) .+$)+ 
0

是否必須只能使用grep或也行吟詩人r命令可用? 我想說的是

grep "<.* " messages.log | sed 's/.*\<\(.*\) \[.*/\1|/g' | tr -d '\n' | sed 's/.$//' 

第一個grep的是刪除數據未按照你想要的圖案,接着爲您的sed命令。 在輸出時,誰應該像

F280| 
F281| 
F280| 
F281| 

最後tr命令只是在每行的末尾刪除換行符(即它加到結果),而最後的sed只是刪除最後一個豎線分隔符

+0

這條管道是過度殺傷。但是'grep -o「<[^] *」file'的一些提示會更好地過濾結果,'sed'不需要做太多的工作。如果你有'GNU grep',那麼使用積極的look-behind可以讓你得到'grep -Po'(?<= <)[^] *「file',那麼需要一些簡單的工作來重新格式化'grep - Po「(?<= <)[^] *」file | tr'\ n''|' | sed's/| $ //''但是正如我的回答顯示'awk'是一個很好的工具。 – 2013-03-28 11:24:33