grep - 显示匹配线的两个部分

时间:2018-01-26 08:58:10

标签: regex grep zsh

我已经阅读了grep的手册并尝试了一些事情,但没有一个能够工作,至少不适合我。

我想在拖尾日志时提取一条好的可读行。 这是我想要美化的日志文件中的通用行:

26 Jan 2018 08:32:29,309 [TEXT] (myService-0) long.text.I.dont.care.about.but.is.different.in.every.line: [OTHERTEXT] Text im actually interested in

我想要的是:

26 Jan 2018 08:32:29,309 [TEXT] [OTHERTEXT] Text im actually interested in

我知道grep -o -e ".*\[TEXT\]"我得到第一部分,grep -o -e "\[OTHERTEXT\].*"得到第二部分。

但这不会显示在一行上,如果我将其合并到grep -o -e ".*\[TEXT\]" -e "\[OTHERTEXT\].*"

中也不会显示

[TEXT][OTHERTEXT]总是存在并且是我的'分隔符',因此可用于支持提取我需要的部分。

我最初认为我可以使用grep -o -e "(.*\[TEXT\]).*(\[OTHERTEXT\].*)"然后以某种方式使用匹配的组$1$2,但要么我没有看到它,要么就没有办法这样做。

有没有办法实现我想要的?

首选使用grep(仅仅因为我想了解更多信息),但如果无法做到这一点,那么awksed也可以,只需要可与tail -f一起使用。

我也对其他方法持开放态度,所以让我知道到达那里的方法。

谢谢,托比亚斯

5 个答案:

答案 0 :(得分:4)

您可以使用sed

sed -E 's/(\[TEXT]).*(\[OTHERTEXT])/\1 \2/' file.log

26 Jan 2018 08:32:29,309 [TEXT] [OTHERTEXT] Text im actually interested in

sed匹配[TEXT][OTHERTEXT]之间的模式,并将其捕获为2组。在替换中,它使用反向引用\1 \2

来回放这些标记

答案 1 :(得分:1)

使用awk,您可以使用]替换[] [之间的所有内容:

$ awk 'sub(/\].*\[/,"] [")' file
26 Jan 2018 08:32:29,309 [TEXT] [OTHERTEXT] Text im actually interested in

答案 2 :(得分:0)

将你的grep传递给

<your grep> | sed "s/(myService-0).*[OTHERTEXT]/(myService-0)[OTHERTEXT]/"

答案 3 :(得分:0)

您可以使用perl

执行此操作
$ # note that this will print empty lines when no match is found
$ perl -lne 'print /(.*\[TEXT\] ).*(\[OTHERTEXT\].*)/' ip.txt
26 Jan 2018 08:32:29,309 [TEXT] [OTHERTEXT] Text im actually interested in
$ # you can avoid empty lines by checking for match first
$ perl -lne '/(.*\[TEXT\] ).*(\[OTHERTEXT\].*)/ && print $1,$2' ip.txt
26 Jan 2018 08:32:29,309 [TEXT] [OTHERTEXT] Text im actually interested in

由于您正在处理tail -f输出,因此您可能需要缓冲控制,例如,请参阅How to 'grep' a continuous stream?

答案 4 :(得分:0)

你可能需要 sed 来做你想做的事情:

sed -E 's/(.*\[TEXT]).*(\[OTHERTEXT])/\1 \2/' 

但要回答有关如何在 grep 中显示匹配项的问题,是的,可以使用选项-o。此选项仅显示匹配行的匹配部分。不过,如果你使用

grep -o -e ".*\[TEXT\]" -e "\[OTHERTEXT\].*"

你将获得匹配的部分,但是分开排列。

另一种可能性是使用前瞻和后视表达式,但它不适用于你的情况。