使用正则表达式提取子字符串

时间:2013-03-28 10:45:36

标签: regex sed awk

我想从我的日志文件中将<提取到下一个

$>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

正则表达式看起来如何?

4 个答案:

答案 0 :(得分:2)

我不会创建一个不可读的正则表达式来执行此操作我在这里使用awk

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

答案 1 :(得分:1)

试试这个:

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

答案 2 :(得分:0)

尝试类似的东西(你将拥有嵌套组),或在正则表达式中打开多行选项:

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

答案 3 :(得分:0)

是否必须仅使用grep或其他命令? 我会说那个

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

第一个grep是删除不符合所需模式的数据,然后是sed命令。 在输出上,谁应该看起来像

F280|
F281|
F280|
F281|

最后一个tr命令只删除每行末尾的换行符(即连接结果),而最后一个sed只是删除最后的管道分隔符