仅当下一行不包含特定匹配项时才打印一行


12

我正在尝试在日志文件中搜索未完成的已记录活动。例如,我记录“ ID 1234的启动活动...”,如果成功,则下一行将为“ Activity 1234 Completed”。

我正在尝试获取“开始...”行,其后没有相应的“已完成”行。

日志文件示例

Starting activity for ID 1234
ID 1234 completed successfully
Starting activity for ID 3423
ID 3423 completed successfully
Starting activity for ID 9876
ID 9876 completed successfully
Starting activity for ID 99889
ID 99889 completed successfully
Starting activity for ID 10011
ID 10011 completed successfully
Starting activity for ID 33367
Starting activity for ID 936819
ID 936819 completed successfully

在此示例中,我将寻找以下输出:

Starting activity for ID 33367

...因为它后面没有“完成”行。

我曾尝试使用grep和进行此操作awk,但并没有取得太大的成功。我假设可以使用其中一种工具来完成此操作,但是我grepawk印章的操作并不先进。

寻找一个快速和可靠的grepawk图案给我需要这里的结果。


我认为grep + awk并不容易,但是您能解释一下为什么这样做吗?所有正在运行的活动的输出,例如是否成功?
雏菊

@ warl0ck,我正在寻找“未完成”。
PattMauler 2012年

Answers:


10

这是一个awk替代方案:

awk '
  /^Starting/ { I[$5] = $0                  }
  /^ID/       { delete I[$2]                }
  END         { for (key in I) print I[key] }
' infile

输出:

Starting activity for ID 33367

I关联数组跟踪的IDS已经看到的。


这确实非常有效,因为它似乎可以适应“开始...”和“已完成...”日志行不相邻/不连续的情况。谢谢@Thor!
PattMauler 2012年

别客气。这应该在(几乎)任意大小的输入上有效地工作,因为它仅存储ID,并且查找时间为O(1)。
2012年

真好 仅有一件事:正如我从@RobertL(unix.stackexchange.com/a/243550/135943)中学到的那样,您无需分配值即可创建数组元素。因此I[$5] = 1,您可以使用代替I[$5]。(您不在乎值,只想让元素存在,只需命名即可完成该操作。)
Wildcard

@Wildcard:您是对的,但是在回顾了OP的问题和他所追求的grep类似输出之后,记住整行并在最后输出是更合适的。
2015年

3
sed '$!N;/\n.*completed/d;P;D' <input

这将从输出中删除所有输入行,而不是后面跟匹配完成字符串的行。


2

使用GNU sed的方法如下:

sed -r 'N; /([0-9]+)\n\w+\s+\1/d; P; D' infile
  • N 在模式空间中再读一行。
  • 匹配正则表达式检查是否找到了相同的ID,是否删除了模式空间(d),然后重新启动了循环。
  • 如果不匹配,请打印出模式空间(P)中的第一行并删除(D)。

我看不到这里有任何扩展...所以-r不需要,对吗?
Louis Maddox

1
@lmmx:这是必需的,因为否则捕获组需要进行转义,而+量词也是如此。
2014年

喔好吧!我对其进行了修改,并被告知没有必要,感谢您的澄清
Louis Maddox

1

如果您的安装支持pcregrep,则多行(-M)选项会派上用场。

pcregrep -M -o '\AStarting activity for ID (\d+)\n(?!ID \1)' t.z

ID 33367的开始活动

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.