我正在尝试获取有关某些调试输出的一些琐碎统计数据。
每条调试行的形式如下(class name)(delimiter 1)(object ID)(delimiter 2)(method name)(delimiter 3)(log message)
我想计算有多少行来自哪些方法。
本质上,如果每一行都可以减少到(class name)(delimiter)(method name)
,我想知道日志文件中每个减少出现了多少次。
我可以在 Bash 中运行什么命令来进行计数?
(我在 macOS 上使用 macports 用 GNU 工具替换了大多数默认的 BSD 风格工具。)
我可以使用 提取类名称grep -o -E "^.*(delimiter 1)
,或者使用 提取方法名称grep -o -E "(delimiter 2).*(delimiter 3)"
,或者使用 突出显示两者grep --color=always -E "^.*(delimiter 1)|(delimiter 2).*(delimiter 3)"
。我一直在寻找一种方法来只grep
输出两个匹配项,然后可以运行它们来| uniq -c
进行计数。
有没有办法grep
打印每行的两个匹配项,而不是仅打印一个匹配项或整行?
答案1
本质上,它可以通过
sed -r -n 's/(^.*)(delimiter 1)(.*)(delimiter 2)(.*)(delimiter 3)(.+$)/\1(delimiter)\5/p' <( command that generates debug logs ) | sort | uniq -c | sort -rn
(改编自这里)
.*
可能匹配太多;sed
是贪婪的并且希望尽早匹配尽可能多的内容,因此这些可能需要例如分隔符的否定(如果您有不方便的分隔符,这可能会很复杂)- 从 到
^
很$
重要,如果您的表达式不匹配,整行将sed
在输出中包含不匹配的部分 - 仅在类名和方法名周围需要括号;删除其他意味着更改末尾的数字,因为这些数字按顺序引用括号内的子表达式。 (将它们全部包括在内可以显示输出中发生的更多内容
sed
,例如通过将结尾更改为/\1(delimiter)\5 -- \1\2\3\4\5\6\7/p
) sort
必须先运行,uniq -c
因为uniq -c
只计算连续相同行的运行,非连续相同行得到单独的计数uniq -c
无法替换为,sort -u
因为sort -u
只会删除重复项,不会对它们进行计数- 最后
sort
不一定要回答所问的问题 - 是的,如果你使用正则表达式来解决一个问题,那么现在你有两个问题。