计算匹配模式和匹配上一行的行数

计算匹配模式和匹配上一行的行数

我想统计某个角色被成功删除的次数。问题是日志文件的一行将显示脚本即将删除角色:

Prepare to remove role X

下一行将告诉我删除是否成功:

删除成功:

Delete Successful

删除失败:

Failed to delete role X: error code

如何统计角色删除成功的次数?我只想使用以下 grep:

grep "Delete Successful" | wc -l

但是,我还将删除以与上述角色相同的方式记录的策略。 IE:

Prepare to delete policy X
Delete Successful

或者

Failed to delete policy X: error code

有什么方法可以在一行上搜索“准备删除角色”,然后计算下一行显示“删除成功”的次数吗?

答案1

如果您使用的grep是 GNU grep,这里有一个快速但肮脏的解决方案:

grep -A1 "Prepare to remove role" | grep "Delete Successful" | wc -l

grep 选项-A1告诉 grep 打印匹配行以及匹配行后面的一行。然后第二个 grep 仅打印删除成功的行。

请注意,只有当“准备删除角色 X”行始终紧跟着“删除成功”行时,此操作才能可靠地工作。

另请注意:您不需要,wc -l因为 grep 内置了该功能:

grep -A1 "Prepare to remove role" | grep -c "Delete Successful"

答案2

使用 awk:

awk '/Delete Successful/ && last_line ~ /Prepare to remove role/ {n++}
     {last_line=$0}
     END {print n+0}'

答案3

假设这些是“删除成功”进入日志的唯一两种方式,为什么不使用一点数学知识呢?

SUCCESS=$(grep 'Delete Successful' | wc -l)
POLICY_COUNT=$(grep 'Prepare to delete policy X' | wc -l)
POLICY_FAIL=$(grep 'Failed to delete policy X' | wc -l)
POLICY_SUCCESS=$(( $POLICY_COUNT - $POLICY_FAIL ))
ROLE_SUCCESS=$(( $SUCCESS - $POLICY_SUCCESS ))

答案4

(由于事实证明纯 shell 算法比外部工具慢得多,因此我只是删除了对它们的所有引用。不过基准数据可能很有趣。)

测试数据:

Prepare to remove role foo
Delete Successful
Prepare to remove role bar
Failed to delete role bar: 1
Prepare to remove policy baz
Delete Successful
Prepare to remove role ban
Delete Successful
something
else
Prepare to remove role bay
Failed to delete role bar: 2
Prepare to remove role bat
Failed to delete role bar: 1

基准将上面的测试数据重复一次百万次(即 306 MB),三个交错运行中的最佳结果,按real时间增加排序:

  • grep:1.115秒。
  • awk:1.778秒。

测试代码:

for index in {1..3}
do
    for path in grep.sh awk.sh
    do
        echo "$path:"
        time bash "$path"
        echo
    done
done

测试系统:Intel Core i7 @ 3.07 GHz,具有 6 GB RAM。

相关内容