【问题标题】:Grep out the last matching line of a text file which line contains a given string, and doesn't start with another string查找文本文件的最后一个匹配行,该行包含给定的字符串,并且不以另一个字符串开头
【发布时间】:2016-10-03 08:57:17
【问题描述】:

我想分析一个日志文件,并寻找一个 IP 地址。日志文件如下所示:

<date> -> <IP address>

例如:

2016-06-02 11:46:33 +0200 -> 86.171.55.134

所以我想选择包含给定 IP 的最后一行,并且该行不是以今天的日期(2016-06-02)开头,不幸的是我的第一次尝试不起作用:

tac logfile.txt|grep -P  '^(?<!2016-06-03).*?86.171.55.134'

通过这种方式我成功地使其工作,但我想制定一个更通用的方式,我可以在哪里使用 .* 或 .*?而不是 19 点,因为有时两种模式之间存在更多且未知长度的数据:

tac logfile.txt|grep -aP -m1 '(?<!2016\-06\-03)...................86.171.55.134'

这里有 5000 行实际的日志数据来玩:

http://www.filefactory.com/file/2sdj77aqflxp/5000.txt

只有 IP 地址是伪造的。

【问题讨论】:

标签: bash perl logging grep pcre


【解决方案1】:

^(?&lt;!2016-06-03).*?86.171.55.134 这个正则表达式永远不会起作用,让我们分解来理解:

^                # Start of line
 (?<!2016-06-03) # Negative look behind searching for 2016-06-03

行首之前可以有什么吗?

您可能想尝试将其更改为前瞻:

tac logfile.txt | grep -P '^(?!2016-06-03).*?86.171.55.134'

或使用 sed:

tac logfile.txt | sed -n '/^2016-06-03/!{/86\.171\.55\.134/p}'

如果你只想要第一个(最后一个因为tac)匹配:

tac logfile.txt | sed -n '/^2016-06-03/!{/86\.171\.55\.134/{p;q}}'

【讨论】:

  • sed 方法有效,grep 方法无效,它打印一行以不需要的日期开头。
  • 在日期字符串之前什么都没有,它是行的开头。
  • @Konstantin 什么不能与 grep 一起使用?
  • 它打印了很多行,日期不正确。 Sed 解决方案甚至更快。
【解决方案2】:

这将对其中包含 IP 的行进行 grep,然后删除具有今天日期的行。 (广义的方式)和头部只砍第一个。

tac data |grep  "86.171.55.134" |grep -v "`date +%Y-%m-%d`" |head -1
2016-06-02 11:46:33 +0200 -> 86.171.55.134

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-06-16
    • 1970-01-01
    • 1970-01-01
    • 2014-05-25
    • 1970-01-01
    • 2011-09-25
    • 1970-01-01
    相关资源
    最近更新 更多