用awk提取nginx日志访问量前十url路径及次数:以双引号分隔取第二域(请求行),正则匹配首个空格后、次个空格前的路径,统计并逆序排序取前10。

用 awk 提取 Nginx 日志中访问量前十的 URL 路径及请求次数,关键是正确解析日志格式、按路径分组统计、再排序取前 10。默认 Nginx 的 log_format 是 combined,URL 路径在第 7 字段(空格分隔),但要注意引号和特殊字符干扰。
确认日志字段位置并提取路径
Nginx combined 日志类似:
192.168.1.1 - - [10/Jan/2024:12:34:56 +0800] "GET /api/v1/users?limit=10 HTTP/1.1" 200 1234 "https://example.com" "Mozilla/5.0..."
URL 路径是 "GET /path?query HTTP/1.1" 中的 /path?query 部分。直接用空格切分不可靠(因 query string 含空格),稳妥做法是用双引号分割,取第二个引号内的内容再截取路径。
- 用
awk -F'"' '{print $2}'提取整个请求行(如GET /api/v1/users?limit=10 HTTP/1.1) - 再用
awk '{print $2}'取其中第二列(即路径部分),自动忽略 query string 中的空格影响
统计并排序取 Top 10
将路径提取、计数、排序、截断整合为一条命令:
awk -F'"' '{split($2,a," "); print a[2]}' access.log | sort | uniq -c | sort -nr | head -10
说明:
-
awk -F'"' '{split($2,a," "); print a[2]}':以双引号为域分隔符,取第二个域(请求行),再按空格拆分,输出第二项(路径) -
sort | uniq -c:先排序再合并重复行并计数 -
sort -nr:按数值(-n)逆序(-r)排序,使次数高的在前 -
head -10:取前 10 行
处理带空格或编码路径的健壮写法
若日志中路径含空格(如某些 POST 请求体被误记)、或需解码(如 %20 → 空格),基础 awk 不够用。可改用更鲁棒的方式:
awk -F'"' 'NF>=2 {match($2, / [^ ]+ /); if(RSTART) print substr($2,RSTART+1,RLENGTH-2)}' access.log | sort | uniq -c | sort -nr | head -10
该写法用 match() 正则匹配第一个空格后、下一个空格前的内容,更准确提取路径,避开 query string 干扰。
输出美化(可选)
让结果更易读,加表头并右对齐次数:
awk -F'"' '{split($2,a," "); print a[2]}' access.log | sort | uniq -c | sort -nr | head -10 | awk '{printf "%-8s %s\n", $1, $2}'
或直接用 awk 一步完成全部逻辑(避免管道开销):
awk -F'"' 'NF>=2 {match($2, / [^ ]+ /); if(RSTART) url=substr($2,RSTART+1,RLENGTH-2); count[url]++} END {for (u in count) print count[u], u}' access.log | sort -nr | head -10
不复杂但容易忽略字段边界和空格问题,抓准请求行里路径的位置,再分组统计就稳了。











