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

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

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

我试图获取“开始...”行,该行后面没有相应的“已完成”行。

日志文件示例

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

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

我尝试过使用 和 来做到这一点grepawk但没有取得太大成功。我假设可以使用这些工具之一来完成,但我的grep能力awk并不先进。

寻找一种快速可靠的grep模式awk来给出我需要的结果。

答案1

这是一个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跟踪已看到的 id。

答案2

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

这将从输出中删除后面没有与字符串匹配的行的所有输入行完全的

答案3

以下是使用 GNU sed 执行此操作的方法:

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

答案4

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

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

开始 ID 33367 的活动

相关内容