【问题标题】:How to grep a line with unknown distance before a line如何在一条线之前grep一条未知距离的线
【发布时间】:2015-05-07 09:42:57
【问题描述】:

我知道我可以在某个模式的上方和下方 grep 行,例如 this
现在有个问题,想grep某个模式前的一行,但是不知道多远,比如:

Time 00:00:01
kkk
lll
aaa
...
Time 00:00:03
kkk
kkk
kkk
lll
lll
aaa
aaa
...
Time 00:00:04
kkk
lll
...

我的目标模式是 aaa,另一个模式是“Time xx:xx:xx”,我想要这样的输出

Time 00:00:01
aaa
Time 00:00:03
aaa
aaa

Time 00:00:01
aaa
Time 00:00:03
aaa
Time 00:00:03
aaa

我该怎么做?

【问题讨论】:

  • aaa有什么意义?
  • 所以您想匹配出现在某些Time 00:XX 块中的aaa 并打印这两个值?

标签: regex bash


【解决方案1】:

为了您的确切输出

awk '/^Time/{a=$0}/aaa/{print a"\n"$0}' file

Time 00:00:01
aaa
Time 00:00:03
aaa
Time 00:00:03
aaa

awk '/^Time/{a=$0;x=0}/aaa/{print (x++?"":a"\n") $0}' file

Time 00:00:01
aaa
Time 00:00:03
aaa
aaa

【讨论】:

  • 非常感谢,你给了我想要的^^
  • 无法联系您!
【解决方案2】:

您可以使用以下内容:

(Time[^\n]*|aaa)

https://regex101.com/r/cY8jN7/2

grep中使用同样的东西:

Time[^\n]*|aaa

编辑:此正则表达式将替换除您需要的所有内容,因此输出正确:

Time[^\n]*\n((?:(?!Time|aaa)[^\n]*(\n|$))*(?=Time|$))|(?<=\n)(?!Time|aaa)[^\n]+\n

https://regex101.com/r/xP1hT0/1

【讨论】:

  • 这不也打印时间没有 aaa 吗?
  • 你会如何使用新的? grep -P 'Time[^\n]*\n((?:(?!Time|aaa)[^\n]*(\n|$))*(?=Time|$))|(?&lt;=\n)(?!Time|aaa)[^\n]+\n' 不返回任何内容。
  • Nvm, grep 只能匹配单行,所以多行正则表达式不起作用,尽管正则表达式对某些东西有效:)。
【解决方案3】:

这是在 Perl 中实现的一种方法:

perl -ane '$t=$_ if /Time/; print $t,$_ if /aaa/' file

【讨论】:

    【解决方案4】:

    用 grep 真的很简单:

    $ grep -E 'Time |aaa' file
    

    匹配器选择

    -E, --extended-regexp 将 PATTERN 解释为扩展的正则表达式(ERE,参见 以下)。 (-E 由 POSIX 指定。)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-07-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-04-26
      • 2020-05-07
      • 2019-10-31
      • 2015-05-13
      相关资源
      最近更新 更多