Linux怎么编写脚本自动统计过去一小时访问频次最高的前20个URL

夏强姑娘_8610

夏强姑娘_8610

2026-10-24

153人浏览

原创

核心思路是用 date 生成一小时前时间戳,awk 按日志第4字段前缀匹配并过滤2xx状态及get/post请求,用 match 提取双引号内url路径,再经 sort | uniq -c | sort -nr | head -20 统计top20。

linux怎么编写脚本自动统计过去一小时访问频次最高的前20个url

用 awk + sort + head 快速提取访问最多的20个URL

核心思路是:从 Web 日志(如 Nginx 的 /var/log/nginx/access.log)中筛选过去一小时内日志行,提取 URL 字段(通常是第 7 或第 8 列),去重计数后取 Top 20。

关键难点不在排序,而在「准确截取过去一小时」——awk 本身不擅长时间计算,得靠 date 配合字符串比对。

  • 假设日志时间格式为 [12/Jul/2024:15:32:18 +0800](Nginx 默认),需先用 date -d '1 hour ago' 生成起始时间字符串,再用 awk 行级匹配
  • URL 在日志中位于请求行,即双引号包围的第二字段($7 对应 "GET /path?x=1 HTTP/1.1"),需用 match() + substr() 提取路径部分,避免把整个请求行当 URL
  • 别直接用 cut -d' ' -f7 —— 若 URL 含空格(如编码后带 %20),会切错列

处理时间范围:用 date 生成动态时间戳做字符串前缀匹配

Nginx 日志时间是固定宽度格式([12/Jul/2024:15:32:18),可截取前 17 位(到分钟)做前缀比较,比逐字段解析快得多,也避开了时区转换问题。

实操命令片段:

start_time=$(date -d '1 hour ago' +'%d/%b/%Y:%H:%M')

然后在 awk 中用 >= "[\"$start_time" 判断(注意日志第 4 字段是带方括号的时间字段)。

Obsidian (Linux)
Obsidian (Linux)

操作 Obsidian 库(纯 Markdown 笔记),并通过 notesmd-cli 实现自动化。

下载
  • 必须加 [ 前缀,否则 01/Jan/2024:00:00 会匹配到 10/Jan/2024:00:00
  • 用 date -d '1 hour ago' 而非 $(($(date +%s) - 3600)),避免手动转秒再格式化,易出时区或闰秒偏差
  • 如果日志用 UTC 时间而服务器本地是 CST,date -d 默认按本地时区解析,需显式加 UTC: date -d '1 hour ago UTC'

提取 URL 时过滤掉非 GET/POST 请求和状态码非 2xx 的干扰项

统计「访问频次」通常只关心成功响应的页面请求,忽略 HEAD、OPTIONS、404、500 等噪音数据。

完整管道示例:

awk -v start="[$(date -d '1 hour ago' +'%d/%b/%Y:%H:%M')" '$4 >= start && $9 == "200" && $6 ~ /^"(GET|POST)/ { match($7, /"[^"]+/); url = substr($7, RSTART+1, RLENGTH-1); if (url != "") print url }' /var/log/nginx/access.log | sort | uniq -c | sort -nr | head -20
  • $9 == "200" 可换成 $9 ~ /^2../ 匹配所有 2xx 状态码
  • $6 ~ /^"(GET|POST)/ 确保只统计标准请求方法;若要包含 PUT 或 DELETE,调整正则即可
  • URL 提取逻辑 match($7, /"[^"]+/) 兼容 "GET /api/v1/users HTTP/1.1" 和 "POST /login?next=%2F HTTP/1.0",不依赖空格分隔

写成可执行脚本时注意日志轮转与权限问题

直接读 /var/log/nginx/access.log 很可能失败:文件权限通常是 root:adm,且生产环境常启用了 logrotate,一小时前的日志可能已压缩或移走。

  • 脚本应检查 access.log 是否存在,再 fallback 到 access.log.1 或最近的 .gz 文件(用 zcat 处理)
  • 避免硬编码路径,用 LOG_PATH=${1:-/var/log/nginx/access.log} 支持传参
  • 若以普通用户运行,需提前配置 sudo 权限(如 www-data ALL=(ALL) NOPASSWD: /bin/zcat),而不是直接给脚本加 setuid —— 极不安全
  • 别忽略 LC_ALL=C 环境变量,否则 sort | uniq 在中文 locale 下可能排序异常或去重失效

最易被忽略的是:Nginx 日志格式可能被自定义过(比如加了 $request_length 或去掉 $http_user_agent),导致 $7 不再是请求行。务必先用 head -1 /var/log/nginx/access.log 确认字段位置。

相关专题

更多
磁盘配额是什么
磁盘配额是什么

磁盘配额是计算机中指定磁盘的储存限制,就是管理员可以为用户所能使用的磁盘空间进行配额限制,每一用户只能使用最大配额范围内的磁盘空间。php中文网为大家提供各种磁盘配额相关的内容,教程,供大家免费下载安装。

2023.06.21

4190

4

如何安装LINUX
如何安装LINUX

本站专题提供如何安装LINUX的相关教程文章,还有相关的下载、课程,大家可以免费体验。

2023.06.29

3553

10

linux find
linux find

find是linux命令,它将档案系统内符合 expression 的档案列出来。可以指要档案的名称、类别、时间、大小、权限等不同资讯的组合,只有完全相符的才会被列出来。find根据下列规则判断 path 和 expression,在命令列上第一个 - ( ) , ! 之前的部分为 path,之后的是 expression。还有指DOS 命令 find,Excel 函数 find等。本站专题提供linux find相关教程文章,还有相关

2023.06.30

2773

5

linux修改文件名
linux修改文件名

本专题为大家提供linux修改文件名相关的文章,这些文章可以帮助用户快速轻松地完成文件名的修改工作,大家可以免费体验。

2023.07.05

6790

7

linux系统安装教程
linux系统安装教程

linux系统是一种可以免费使用,自由传播,多用户、多任务、多线程、多CPU的操作系统。本专题提供linux系统安装教程相关的文章,大家可以免费体验。

2023.07.06

6442

7

linux查看文件夹大小
linux查看文件夹大小

Linux是一种自由和开放源码的类Unix操作系统,存在着许多不同的Linux版本,但它们都使用了Linux内核。Linux可安装在各种计算机硬件设备中,比如手机、平板电脑、路由器、视频游戏控制台、台式计算机、大型机和超级计算机。linux怎么查看文件夹大小呢?php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

2023.07.20

3713

8

linux查看ip命令
linux查看ip命令

本专题为大家提供linux查看ip命令相关文章内容,感兴趣的朋友可以免费下载体验试试。

2023.07.20

3205

4

linux查看cpu使用率
linux查看cpu使用率

在linux的系统维护中,可能需要经常查看cpu使用率,分析系统整体的运行情况。本专题为大家带来了linux查看cpu使用率的相关文章,感兴趣的朋友千万不要错过了。

2023.07.25

3439

6

linux查找文件命令
linux查找文件命令

Linux是一种自由和开放源码的类Unix操作系统,存在着许多不同的Linux版本,但它们都使用了Linux内核。Linux可安装在各种计算机硬件设备中,比如手机、平板电脑、路由器、视频游戏控制台、台式计算机、大型机和超级计算机。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

2023.07.31

297

3

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
尚观shell视频教程
尚观shell视频教程

共8课时 | 1.9万人学习

Python uv官方安装与入门文档
Python uv官方安装与入门文档

共0课时 | 0人学习

Buffalo框架快速入门指南
Buffalo框架快速入门指南

共0课时 | 0人学习