Bash 命令计算两个不同位置具有匹配子字符串的行数

Bash 命令计算两个不同位置具有匹配子字符串的行数

我正在尝试获取有关某些调试输出的一些琐碎统计数据。

每条调试行的形式如下(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不一定要回答所问的问题
  • 是的,如果你使用正则表达式来解决一个问题,那么现在你有两个问题。

相关内容