除以两个grep和字数的结果

时间:2017-01-05 14:32:19

标签: zsh

我有一个日志文件,我想将一个grep的结果除以另一个grep并计数。

$ echo $((cat log2.txt | grep timed\|error\|Error | wc -l)/(cat log2.txt | grep Duration | wc -l))
zsh: bad math expression: operator expected at `log2.txt |...'

它很丑陋,不起作用,我可以用更好的方式做到但我不知道如何做。

此外,我想知道是否可以在尾部读取的日志流上增加id。例如。

2 个答案:

答案 0 :(得分:2)

首先,您应该知道,grep|wc -l将计算匹配行数而不是出现次数,我希望这是您真正想要的

关于你的要求,你的方法确实是丑陋的(7个过程),除了错误。这项工作可以通过一个awk行来完成:

awk '/timed|[Ee]rror/{a++}/Duration/{b++}END{printf "%.2f\n",a/b}' log2.txt

以上行根据匹配的行数计算结果,与grep|wc -l相同。

答案 1 :(得分:1)

你有几个问题:

  1. 您正在尝试直接在算术表达式中运行shell命令。
  2. 您没有将正确的正则表达式传递给grep
  3. 您需要确保至少有一个操作数是浮点值才能触发zsh的浮点除法。
  4. 每个管道也可以简化为单个命令;使用输入重定向而不是cat,并使用-c选项获取与正则表达式匹配的行数。

    echo $(( 1.0 * $(grep -c 'timed\|error\|Error' log2.txt) / $(grep -c Duration log2.txt))
    

    基本正则表达式将未转义的|视为文字字符,而不是转换运算符。

    $ echo foo | grep foo\|bar
    $ echo foo | grep foo\\\|bar   # Pass a literal backslash as part of the regex
    foo
    $ echo foo | grep 'foo\|bar'   # Use '...' instead of explicitly escaping \ and |
    foo
    $ echo foo | grep -E 'foo|bar'  # Use extended regular expressions instead