代码之家  ›  专栏  ›  技术社区  ›  ximarin

grep-显示匹配线的两部分

  •  3
  • ximarin  · 技术社区  · 7 年前

    我阅读了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 (只是因为我想了解更多),但如果不可能的话 awk sed 也很好,只需与 tail -f .

    我也愿意接受其他方法来达到这一点,所以请告诉我有哪些方法可以达到这一点。

    谢谢Tobias

    5 回复  |  直到 7 年前
        1
  •  4
  •   anubhava    7 年前

    您可以使用 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] 并将其分为两组。作为替代,它使用反向引用将这些标记放回原处 \1 \2

        2
  •  1
  •   James Brown    7 年前

    使用awk,您可以在 ] [ 具有 ] [ :

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

    将你的grep导入

    <your grep> | sed "s/(myService-0).*[OTHERTEXT]/(myService-0)[OTHERTEXT]/"
    
        4
  •  0
  •   Sundeep    7 年前

    你可以用 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? 例如

        5
  •  0
  •   rools    7 年前

    你可能需要 sed公司 做你想做的事:

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

    但要回答您关于如何在中显示匹配项的问题 格雷普 ,是的,使用该选项是可能的 -o . 此选项将仅显示匹配线的匹配部分。然而,如果您使用

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

    您将获得匹配的零件,但在单独的行中。

    另一种可能是使用“向前看”和“向后看”表达式,但它在您的情况下不起作用。