Zsh 将两个grep的结果除以单词计数

Zsh 将两个grep的结果除以单词计数,zsh,Zsh,我有一个日志文件,我想把一个grep和count的结果除以另一个grep和count $ 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 |...' 它很难看,不起作用,我可能可以用更好的方式来做,但我不知道怎么做 此外,我还想知道是否有

我有一个日志文件,我想把一个grep和count的结果除以另一个grep和count

$ 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 |...'
它很难看,不起作用,我可能可以用更好的方式来做,但我不知道怎么做


此外,我还想知道是否有可能在通过tail读取的日志流上递增id。

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

关于你的需求,事实上,你的方法是丑陋的(7个过程),除了错误。这项工作可以通过一条awk生产线完成:

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

上面这一行根据匹配的行数计算结果,与您的
grep | wc-l
相同。首先,您应该知道,两个
grep | wc-l
都将计算匹配行数,而不是出现次数,我希望这是您真正想要的

关于你的需求,事实上,你的方法是丑陋的(7个过程),除了错误。这项工作可以通过一条awk生产线完成:

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

上面的行根据匹配的行数计算结果,与您的
grep | wc-l
相同,您有几个问题:

  • 您正试图在算术表达式中直接运行shell命令
  • 您没有将正确的正则表达式传递给
    grep
  • 您需要确保至少有一个操作数是浮点值,以触发
    zsh
    的浮点除法
  • 每个管道也可以简化为单个命令;使用输入重定向而不是
    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
    

    您有几个问题:

  • 您正试图在算术表达式中直接运行shell命令
  • 您没有将正确的正则表达式传递给
    grep
  • 您需要确保至少有一个操作数是浮点值,以触发
    zsh
    的浮点除法
  • 每个管道也可以简化为单个命令;使用输入重定向而不是
    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
    

    你期望什么样的产出?Bash/sh不能直接进行浮点运算。我想要一种脚本语言(Perl/Ruby/Python)。您可能的副本没有足够的
    字符。您转义它只是为了避免shell将其视为管道的一部分,但是
    grep
    仍然将其视为文字字符,而不是转换运算符,除非再次转义。
    grep timed\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\/code>或(最简单的)grep-E'timed\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\。您还需要在命令替换中运行命令,以将输出用作算术表达式中的操作数:
    $($(cat…wc-l)/$(cat…wc-l))
    。您希望得到什么输出?Bash/sh不能直接进行浮点运算。我想要一种脚本语言(Perl/Ruby/Python)。您可能的副本没有足够的
    字符。您转义它只是为了避免shell将其视为管道的一部分,但是
    grep
    仍然将其视为文字字符,而不是转换运算符,除非再次转义。
    grep timed\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\/code>或(最简单的)grep-E'timed\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\。您还需要在命令替换中运行命令,以将输出用作算术表达式中的操作数:
    $($(cat…wc-l)/$(cat…wc-l))
    。我需要的是非常完美的“匹配行数”。{a++}是什么意思?非常感谢@BeniMio如果你知道C或C++,你就知道一个++。这与
    a+=1
    相同,我需要的是完美的“匹配行数”。{a++}是什么意思?非常感谢@BeniMio如果你知道C或C++,你就知道一个++。这与
    a+=1
    非常感谢您的额外解释。非常感谢您的额外解释。