【问题标题】:Unix grep, sed, awk commands to find average response time of a request from log filesUnix grep、sed、awk 命令从日志文件中查找请求的平均响应时间
【发布时间】:2019-09-28 03:54:53
【问题描述】:

要求是从一堆日志文件中找到 API 调用的平均响应时间。 从日志文件中,我想过滤选择模式的日志:

Eligible programs received from program service for user '89e45876-6ae7-2d08-217c-7320aada1a3d' in 840 ms.

然后取所有响应时间的平均值。

我使用 grep、sed 和 awk 命令编写了以下代码,用于打印每个日志文件的平均响应时间。

for file in *; do 
    if [ -f "$file" ]; then 
        cat $file | grep ".*Eligible programs received from program service for user .*" | sed -E -n "s/.*Eligible programs received from program service for user .* in (.*) ms.*/\\1/p" | awk '{ SUM += $1; COUNT += 1;} END { print SUM/COUNT }'
    fi 
done

但我想要为所有日志文件计算一个平均值。我该如何修改上面的程序来实现它。

【问题讨论】:

    标签: unix awk sed grep


    【解决方案1】:

    如果您想逐个文件获取平均文件,请尝试关注(使用 GNU awk),感谢@Jotne 指出 count=""。

    awk '
    /Eligible programs received from program service for user/{
      sum+=$(NF-1)
      count++
    }
    ENDFILE{
      print "Avg=" sum/count
      count=sum=""
    }
    ' /path/to/your/files/*
    


    编辑:如果您想要所有文件的平均值,请尝试:

    awk '
    /Eligible programs received from program service for user/{
      sum+=$(NF-1)
      count++
    }
    END{
      print "Avg=" sum/count
    }
    ' /path/to/your/files/*
    

    【讨论】:

    • Ravinder Singh,感谢您的及时回复。它不工作。但是,相同的命令适用于单个文件。以下命令有效:awk '/Eligible programs received from program service for user/{ sum+=$(NF-1); count++ } END { print sum/count }' recommendationservice.log.2019-09-27
    • ENDFILE 是使用错误的命令,它会给出每个文件的平均响应,但END 会给出所有文件的平均值。如果您喜欢一个文件和一个文件的平均值,则在打印平均值后应将计数器设置为零。
    • @Jotne,谢谢,老实说,我认为用户需要一个一个文件的平均值,现在将编辑答案。
    • 逐个文件也是错误的。您需要为所有文件 END{print "Avg="sum/count} 或每个文件 ENDFILE {print "Avg="sum/count;cunt=0}
    • @Sreenivas 平均总数适用于END,但ENDFILE 每个文件的平均值仍然无法正常工作,sum 也需要重置,所以上面的一些我的错误,正确应该是ENDFILE {print "Avg="sum/count;sum=cunt=0} 所以这就是为什么我总是(如果可能的话)发布我的答案的输出。
    【解决方案2】:

    如果您没有太多文件无法放入 awk arg 列表中,以下是如何同时稳健地执行两项任务(每个文件和总计)的方法:

    #!/bin/env bash
    
    IFS=$'\n' read -r -d '' -a files < <(find . -maxdepth 1 -type f && printf '\0')
    
    awk '
    /Eligible programs received from program service for user/ {
        sum[FILENAME] += $(NF-1)
        cnt[FILENAME]++
    }
    END {
        for (i=1; i<ARGC; i++) {
            file = ARGV[i]
            print file, (cnt[file] ? sum[file] / cnt[file] : 0)
            tot_sum += sum[file]
            tot_cnt += cnt[file]
        }
        print "TOTAL", (tot_cnt ? tot_sum / tot_cnt : 0)
    }
    ' "${files[@]}"
    

    以上内容适用于任何 awk,并且将处理下雨天的场景,例如将目录与您的文件或没有目标字符串的文件在同一目录中。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-03-24
      • 1970-01-01
      • 2017-09-29
      • 2018-10-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多