sed 提取日志 url 路径需按场景选择命令:标准访问日志用 sed -n 's/^1"1\s+(2"])\s+1".*$/\1/p' 提取请求路径;完整 url 用 sed -n 's/.*https?:\/\/[^\/]*\([^[:space:]"]*\).*/\1/p' 提取含查询参数的路径;纯路径则追加 sed 's/\?.*$//' 截断参数。" ↩[:space: ↩

用 sed 提取日志中的 URL 访问路径,关键是匹配 HTTP 请求行(如 GET /path/to/resource HTTP/1.1)或完整 URL 中的路径部分(如 https://example.com/abc?x=1 中的 /abc),然后用替换或打印方式提取。
提取标准访问日志中的请求路径(如 Apache/Nginx 日志)
常见日志格式中,请求行通常在引号内,形如 "GET /api/v2/users?id=123 HTTP/1.1"。我们只需提取 GET 后、空格前的路径(含查询参数):
- 命令:
sed -n 's/^[^"]*"[^"]* \([^ ]*\) [^"]*".*$/\1/p' access.log - 说明:跳过开头非引号内容,匹配第一个引号内的请求行,用
\([^ ]*\)捕获空格分隔的第一个路径字段(即/api/v2/users?id=123) - 更稳妥写法(适配多空格/制表符):
sed -n 's/^[^"]*"[^"]*[[:space:]]+\([^[:space:]"]*\)[[:space:]]+[^"]*".*$/\1/p' access.log(GNU sed 支持+,或改用*+\{1,\})
从完整 URL 中提取路径部分(如日志含 https://...)
若日志记录的是完整 URL(如 curl https://api.example.com/v1/data?format=json 或 JSON 字段值),可用:
- 命令:
sed -n 's/.*\(https\?:\/\/[^/]*\)\(\/[^[:space:]"]*\).*/\2/p' logfile - 说明:第一组匹配协议和域名(丢弃),第二组捕获路径(
/v1/data?format=json),[^[:space:]"]*防止匹配到结尾引号或换行 - 简化版(只关心路径,忽略协议):
sed -n 's/.*https\?:\/\/[^/]*\([^[:space:]"]*\).*/\1/p' logfile
只提取路径不带查询参数(纯 path)
如果只需要 /api/users 而不要 ?id=5&page=1,可在提取后进一步截断:
- 两步法(推荐):
sed -n 's/^[^"]*"[^"]* \([^ ]*\) [^"]*".*$/\1/p' access.log | sed 's/\?.*$//' - 单步法(GNU sed):
sed -n 's/^[^"]*"[^"]* \([^[:space:]?]*\)\(?\|$\)/\1/p' access.log—— 但注意这仅匹配无问号路径;更可靠的是用sed 's/\?.*//'后处理
配合其他工具提高准确性
sed 擅长行内文本替换,但复杂结构建议组合使用:
- 先用
grep过滤含 GET/POST 的行:grep -E '"(GET|POST) ' access.log | sed 's/.*"(GET|POST) ([^ ]*).*/\2/' - 避免误匹配注释或字段值:加锚点或上下文限制,例如
sed -n '/"GET /{s/.*"GET \([^ ]*\).*/\1/p;}' access.log - 处理 JSON 日志时,
sed易出错,此时优先用jq:jq -r '.url | capture("/(?<path>[^?]+)").path' log.json</path>











