当前位置:首页>Linux>Linux的awk、grep、sed组合场景

Linux的awk、grep、sed组合场景

  • 2026-07-04 04:14:10
Linux的awk、grep、sed组合场景
点击标题下「蓝色微信名」可快速关注

技术社群的这篇文章《30s定位大面积故障!如何用awk+grep+sed搭建日志处理神器?》给我们讲解了如何用awk、grep、sed检索日志文件,这个需求看着很琐碎,但其实是非常重要的技能。

无论是开发、运维,如果在Linux平台工作,都可能会有检索文件的需求,相较于Windows,Linux提供了很多便捷的指令,以及全面的参数,可以让我们在海量文件中搜索到需要的,每个指令都蕴藏着设计的精妙。

一、概述

1、背景介绍

2024年双十一那天凌晨三点,我被电话吵醒。线上服务出现大面积超时,用户投诉量激增。登录服务器一看,最近4小时产生了将近12GB的Nginx访问日志。领导在群里催着要故障原因,我需要在最短时间内从这堆日志里找出问题根源。

如果用传统的方式打开日志文件,光是vim加载就得等好几分钟。用Python写脚本?来不及了。这时候,grep、sed、awk这三板斧就成了救命稻草。

我用一行命令组合,30秒内就定位到了问题:某个爬虫IP在疯狂请求一个数据库密集型的接口,直接把数据库连接池打满了。封禁IP后,服务立刻恢复。

这就是Shell三剑客的魅力。干了10年SRE,我越来越觉得,这三个工具是运维工程师的核心竞争力。不管你用多么高级的日志分析平台,遇到紧急情况时,能在命令行里快速处理数据的能力永远不会过时。

2、技术特点

为什么grep、sed、awk能做到如此高效?这得从它们的设计哲学说起。

1)流式处理:三剑客都采用流式处理机制,一次只读取一行到内存,处理完就释放。这意味着处理10GB文件和处理10MB文件的内存消耗是一样的。相比之下,如果你用Python的readlines()把整个文件读进内存,10GB文件直接就把机器干趴下了。

2)C语言实现:这三个工具都是用C语言写的,经过了几十年的优化,底层直接调用系统I/O,效率极高。我做过测试,处理相同的日志文件,awk比Python快5-10倍是很正常的。

3)管道机制:Unix的管道设计是天才之作。多个命令通过管道串联,数据像水一样流过去,不需要中间临时文件。这不仅节省了磁盘I/O,还让命令可以并行执行。

4)正则表达式引擎:grep和sed的正则表达式引擎经过高度优化,特别是grep -F(固定字符串搜索)和GNU grep的DFA引擎,在特定场景下性能惊人。

3、三剑客分工

在实际工作中,我是这样区分三者使用场景的:

1)grep:专注搜索过滤。需要从海量日志中快速找出包含特定关键词的行时用它。它干的活很专一,但干得特别好。

2)sed :擅长文本替换。批量修改配置文件、格式转换、删除特定行等场景用它。我把它理解成"流编辑器",数据流过它的时候被修改。

3)awk:复杂数据处理。需要对字段进行计算、统计、聚合时用它。它其实是一门完整的编程语言,只是我们通常只用到它的一小部分功能。

4、适用场景

根据我的经验,以下场景特别适合用三剑客:

1)故障排查:快速定位错误日志、统计错误频率、找出异常请求

2)日志分析:统计访问量、分析响应时间分布、识别恶意IP

3)配置管理:批量修改配置文件、格式转换、数据清洗

4)数据处理:CSV/JSON处理、报表生成、数据校验

5)自动化脚本:作为Shell脚本的核心组件处理文本数据

不适合的场景也要说清楚:

1)复杂的多文件关联分析:这种场景还是用ELK或者写Python脚本更合适

2)需要持久化存储的场景:三剑客是一次性处理,不会保存状态

3)需要复杂数据结构的场景:awk虽然有数组,但处理复杂嵌套结构还是力不从心

5、环境要求

本文的所有命令都在以下环境测试通过:

操作系统:Ubuntu 22.04 LTS / CentOS 8 / macOS SonomaGNU grep:3.8+GNU sed:4.8+GNU awk (gawk)5.1+ripgrep:14.0+(可选,高性能替代方案)

如果你用的是macOS,系统自带的是BSD版本的工具,语法和GNU版本略有差异。我强烈建议用Homebrew安装GNU版本:

brew install grep sed gawk ripgrep

安装后,GNU版本的命令前缀是g,比如ggrep、gsed、gawk。你也可以在.bashrc里设置别名:

alias grep='ggrep'alias sed='gsed'alias awk='gawk'

版本检查命令:

grep --version | head -1sed --version | head -1awk --version | head -1

二、详细步骤

1、准备工作

1)生成测试数据

在正式开始之前,我们需要一些测试数据。下面这个脚本能生成类似真实环境的Nginx访问日志:

#!/bin/bash# generate_nginx_log.sh - 生成模拟Nginx日志LOG_FILE="access.log"TOTAL_LINES=10000000  # 约1GB# IP池IPS=("192.168.1.100" "192.168.1.101" "10.0.0.50" "10.0.0.51"     "172.16.0.10" "8.8.8.8" "1.1.1.1" "203.0.113.50"     "198.51.100.23" "185.220.101.42")# URL池URLS=("/api/users" "/api/orders" "/api/products" "/api/search"      "/static/js/main.js" "/static/css/style.css" "/images/logo.png"      "/api/payment" "/health" "/metrics" "/api/v2/data")# 状态码STATUS_CODES=("200" "200" "200" "200" "200" "201" "301" "302"              "400" "401" "403" "404" "500" "502" "503")# User-Agent池USER_AGENTS=(    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36"    "Mozilla/5.0 (iPhone; CPU iPhone OS 16_0 like Mac OS X)"    "curl/7.88.1"    "python-requests/2.28.0"    "Googlebot/2.1 (+http://www.google.com/bot.html)")echo "开始生成日志文件,共 $TOTAL_LINES 行..."for ((i=1; i<=TOTAL_LINES; i++)); do    ip=${IPS[$RANDOM % ${#IPS[@]}]}    url=${URLS[$RANDOM % ${#URLS[@]}]}    status=${STATUS_CODES[$RANDOM % ${#STATUS_CODES[@]}]}    ua=${USER_AGENTS[$RANDOM % ${#USER_AGENTS[@]}]}    size=$((RANDOM % 50000 + 100))    response_time=$(awk -v min=0.001 -v max=5.0 'BEGIN{srand(); print min+rand()*(max-min)}')    timestamp=$(date "+%d/%b/%Y:%H:%M:%S +0800")    echo "$ip - - [$timestamp] \"GET $url HTTP/1.1\" $status$size \"$ua\" $response_time"done > "$LOG_FILE"echo "日志生成完成:$LOG_FILE,大小:$(du -h $LOG_FILE | cut -f1)"

这个脚本生成的日志格式是标准的Nginx combined格式,最后多加了一个响应时间字段。1000万行大约1GB,生成时间取决于你的机器性能。

如果你想快速生成更大的文件用于性能测试,可以用下面这个更高效的方法:

# 先生成一个小文件,然后复制扩展head -1000000 access.log > access_small.logfor i in {1..10}; do cat access_small.log >> access_10gb.log; done

2)了解日志格式

在开始处理之前,我习惯先看几行日志,了解数据格式:

head -5 access.log

输出类似:

192.168.1.100 - - [06/Jan/2025:10:23:45 +0800] "GET /api/users HTTP/1.1" 200 1234 "Mozilla/5.0 (Windows NT 10.0; Win64; x64)" 0.045

分析一下字段结构:

  • 字段1:客户端IP

  • 字段2-3:用户标识(通常是-)

  • 字段4-5:时间戳(带方括号)

  • 字段6-7-8:请求行(方法、URL、协议)

  • 字段9:HTTP状态码

  • 字段10:响应大小

  • 字段11+:User-Agent

  • 最后一个字段:响应时间

这个分析过程很重要,因为后面用awk处理时,字段编号直接决定了取数的正确性。

2、核心配置

1)grep核心参数

grep的参数不少,但常用的就那么几个。我按使用频率排序:

# 最常用的参数组合grep -n "ERROR"        # -n 显示行号,排查问题必备grep -i "error"        # -i 忽略大小写grep -c "ERROR"        # -c 只显示匹配行数,快速统计grep -v "DEBUG"        # -v 反向匹配,排除某些行grep -A 5 "Exception"  # -A 显示匹配行后5行,看堆栈grep -B 2 "ERROR"      # -B 显示匹配行前2行,看上下文grep -C 3 "FATAL"      # -C 显示前后各3行grep -l "password"     # -l 只显示包含匹配的文件名grep -r "TODO" ./src   # -r 递归搜索目录grep -w "error"        # -w 全词匹配,避免匹配到errorsgrep -o "ip=[0-9.]+"   # -o 只输出匹配的部分grep -E "err|warn"     # -E 使用扩展正则表达式grep -P "\d{4}"        # -P 使用Perl正则(更强大)grep -F "fixed[str]"   # -F 固定字符串搜索,不解释正则

-E和-P的区别:这是个常见困惑点。-E是POSIX扩展正则,支持+、?、|、()这些元字符不用转义。-P是Perl兼容正则(PCRE),支持更多高级特性,比如\d(数字)、\s(空白)、(?=)(前瞻)等。

我的选择标准:简单匹配用-E,需要用到\d、\w这类简写或者零宽断言时用-P。但要注意,macOS的grep不支持-P参数,需要安装GNU grep。

2)sed核心参数

sed的参数相对少,但理解工作模式很重要:

# 基本替换sed 's/old/new/'       # 替换每行第一个匹配sed 's/old/new/g'      # 替换每行所有匹配sed 's/old/new/gi'     # 全局替换,忽略大小写# 原地修改(危险操作!)sed -i 's/old/new/g' file       # Linux语法sed -i '' 's/old/new/g' file    # macOS BSD语法# 指定行范围sed '10,20s/old/new/g'          # 只处理第10-20行sed '/pattern/s/old/new/g'      # 只处理匹配pattern的行# 删除操作sed '/DEBUG/d'         # 删除包含DEBUG的行sed '1,10d'            # 删除前10行sed '/^$/d'            # 删除空行# 打印操作sed -n '5,10p'         # 只打印第5-10行(-n抑制默认输出)sed -n '/ERROR/p'      # 只打印匹配行# 多个操作sed -e 's/a/b/' -e 's/c/d/'     # 多个-esed 's/a/b/; s/c/d/'            # 分号分隔# 分组和引用sed 's/\(.*\):\(.*\)/\2:\1/'    # 交换冒号两边的内容sed -E 's/(.*):(.*):\2:\1/'     # -E模式下括号不用转义

重要提醒:sed -i会直接修改文件,没有撤销操作。生产环境一定要先备份或者用sed -i.bak创建备份文件。我见过太多人用sed -i把配置文件改坏了,又没有备份,只能从别的机器拷贝。

3)awk核心参数

awk是三剑客中最复杂的,因为它是一门完整的编程语言。核心概念:

# 基本语法awk '{print $1}'               # 打印第一个字段awk '{print $NF}'              # 打印最后一个字段awk '{print NR, $0}'           # 打印行号和整行awk -F: '{print $1}'           # 指定分隔符为冒号awk -F'[,;:]' '{print $1}'     # 多个分隔符# 条件过滤awk '$3 > 100 {print}'         # 第3字段大于100的行awk '/ERROR/ {print}'          # 包含ERROR的行awk 'NR==1 || NR%1000==0'      # 打印第1行和每隔1000行# 内置变量# NR - 当前行号# NF - 当前行的字段数# FS - 字段分隔符# RS - 记录(行)分隔符# OFS - 输出字段分隔符# ORS - 输出记录分隔符# BEGIN和END块awk 'BEGIN{sum=0} {sum+=$1} END{print sum}'   # 求和awk 'BEGIN{FS=":"} {print $1}'                 # 在BEGIN中设置分隔符# 数组awk '{count[$1]++} END{for(ip in count) print ip, count[ip]}'  # 统计频次# 格式化输出awk '{printf "%-15s %10d\n", $1$2}'          # 格式化输出# 内置函数awk '{print length($0)}'       # 字符串长度awk '{print substr($1, 1, 5)}' # 子字符串awk '{gsub(/old/, "new"); print}'  # 替换awk '{print tolower($1)}'      # 转小写
3、启动验证

在正式开始处理日志之前,我习惯先做几个验证:

# 1. 确认文件大小和行数ls -lh access.logwc -l access.log# 2. 看前几行,确认格式head -5 access.log# 3. 看最后几行,确认文件完整tail -5 access.log# 4. 随机抽样检查shuf -n 10 access.log# 5. 检查是否有异常字符file access.log

这些检查能帮你避免很多坑,比如:

  • 文件格式是不是UTF-8(如果有中文可能是GBK)

  • 有没有被截断

  • 行尾是LF还是CRLF(Windows下载的文件经常是CRLF)

三、示例代码和配置

1、完整配置示例

场景一:统计Nginx日志中的TOP10 IP

这是最常见的需求,几乎每次排查问题都会用到:

# 方法1:传统三剑客组合awk '{print $1}' access.log | sort | uniq -c | sort -rn | head -10# 执行流程解析:# awk '{print $1}' - 提取IP地址(第一个字段)# sort - 按IP排序(为uniq准备)# uniq -c - 统计连续相同行的数量# sort -rn - 按数字倒序排列# head -10 - 取前10条# 方法2:纯awk实现(内存占用更低)awk '{ip[$1]++} END{for(i in ip) print ip[i], i}' access.log | sort -rn | head -10# 方法3:如果只关心某个时间段awk '/06\/Jan\/2025:10/ {ip[$1]++} END{for(i in ip) print ip[i], i}' access.log | sort -rn | head -10

性能对比:处理1GB日志(约1000万行)

方法
耗时
内存峰值
方法1
45秒
2GB(sort的临时文件)
方法2
28秒
800MB
方法3
15秒
400MB(过滤后数据量小)

方法2更快的原因是:awk在内存中用关联数组直接计数,避免了中间管道传输和sort的排序开销。

场景二:统计TOP10 URL及其响应时间

# 统计访问量TOP10 URLawk '{print $7}' access.log | sort | uniq -| sort -rn | head -10# 统计平均响应时间TOP10 URL(响应时间在最后一列)awk '{url=$7; time=$NF; count[url]++; sum[url]+=time}     END{for(u in count) printf "%s %.3f %d\n", u, sum[u]/count[u], count[u]}' \     access.log | sort -t' ' -k2 -rn | head -10# 更友好的输出格式awk '{url=$7; time=$NF; count[url]++; sum[url]+=time}     END{         printf "%-40s %10s %10s\n""URL""AvgTime""Count"         printf "%-40s %10s %10s\n""---""-------""-----"         for(u in count)             printf "%-40s %10.3f %10d\n", u, sum[u]/count[u], count[u]     }' access.log | sort -t' ' -k2 -rn | head -12

场景三:找出5xx错误的请求详情

# 找出所有500错误grep '" 500 ' access.log# 找出5xx错误并统计awk '$9 ~ /^5/ {print}' access.log | head -20# 统计5xx错误按URL分布awk '$9 ~ /^5/ {error[$7]++} END{for(u in error) print error[u], u}' \    access.log | sort -rn | head -10    # 统计5xx错误按小时分布(时间字段需要解析)awk '$9 ~ /^5/ {    split($4, t, ":")    hour = t[2]    count[hour]++} END{    for(h in count) print h":00", count[h]}' access.log | sort

场景四:从应用日志提取并聚合错误堆栈

这个需求稍微复杂一些,因为错误堆栈通常跨多行:

# 假设Java日志格式:# 2025-01-06 10:23:45.123 ERROR [main] c.e.Service - Error processing request# java.lang.NullPointerException: null#     at com.example.Service.process(Service.java:45)#     at com.example.Controller.handle(Controller.java:23)# 提取错误信息(ERROR行及其后续堆栈行)sed -n '/ERROR/,/^[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}/p' app.log | sed '$d'# 更实用:提取ERROR和后续5行grep -A 5 "ERROR" app.log# 统计错误类型出现频率grep -oP "Exception: .*" app.log | sort | uniq -c | sort -rn | head -10# 统计异常类名频率grep -oP "[a-zA-Z]+Exception" app.log | sort | uniq -c | sort -rn# 完整的错误聚合脚本awk '/ERROR/ {    error_line = $0    exception = ""    getline    if (/Exception|Error/) {        exception = $0        gsub(/^[ \t]+/, "", exception)    }    if (exception != "") {        errors[exception]++    }}END {    for (e in errors) {        print errors[e], e    }}' app.log | sort -rn | head -20
2、实际应用案例

案例一:批量修改配置文件

场景:需要把所有服务器上的Nginx配置中的worker_processes auto改成worker_processes 8:

# 先预览要修改的文件grep -rl "worker_processes auto" /etc/nginx/# 预览修改效果(不实际修改)sed -n 's/worker_processes auto/worker_processes 8/p' /etc/nginx/nginx.conf# 带备份的原地修改sed -i.bak 's/worker_processes auto/worker_processes 8/' /etc/nginx/nginx.conf# 批量修改所有匹配文件find /etc/nginx -name "*.conf" -exec sed -i.bak 's/worker_processes auto/worker_processes 8/' {} \;# 验证修改结果grep "worker_processes" /etc/nginx/nginx.confdiff /etc/nginx/nginx.conf /etc/nginx/nginx.conf.bak

更复杂的例子:修改Redis配置中的多个参数

# 创建sed脚本文件cat > update_redis.sed << 'EOF's/^maxmemory .*/maxmemory 4gb/s/^maxmemory-policy .*/maxmemory-policy allkeys-lru/s/^# requirepass .*/requirepass YourSecurePassword123/s/^bind 127.0.0.1/bind 0.0.0.0/EOF# 应用修改sed -i.bak -f update_redis.sed /etc/redis/redis.conf# 验证grep -E "^(maxmemory|bind|requirepass)" /etc/redis/redis.conf

案例二:日志分析生成CSV报表

这个需求在月度汇报、容量规划时很常见:

# 生成每小时访问量统计CSVawk 'BEGIN {    FS=" "    OFS=","    print "hour,requests,avg_response_time,error_rate"}{    # 解析时间    split($4, datetime, ":")    hour = datetime[2]    # 统计    requests[hour]++    response_time[hour] += $NF    if ($9 >= 400) errors[hour]++}END {    for (h=0; h<24; h++) {        hh = sprintf("%02d", h)        req = requests[hh] + 0        avg_time = (req > 0? response_time[hh] / req : 0        err_rate = (req > 0? errors[hh] * 100.0 / req : 0        printf "%s:00,%d,%.3f,%.2f%%\n", hh, req, avg_time, err_rate    }}' access.log > hourly_stats.csv# 生成每个URL的详细统计awk 'BEGIN {    OFS=","    print "url,requests,avg_time,min_time,max_time,p99_time"}{    url = $7    time = $NF    count[url]++    sum[url] += time    if (!(url in min) || time < min[url]) min[url] = time    if (time > max[url]) max[url] = time}END {    for (u in count) {        avg = sum[u] / count[u]        printf "%s,%d,%.3f,%.3f,%.3f\n", u, count[u], avg, min[u], max[u]    }}' access.log | sort -t',' -k2 -rn > url_stats.csv

生成可视化友好的报表:

# 使用column命令美化输出awk '{    ip[$1]++    bytes[$1+= $10}END {    printf "%-18s %10s %15s\n""IP Address""Requests""Total Bytes"    printf "%-18s %10s %15s\n""-----------""--------""-----------"    for (i in ip) {        printf "%-18s %10d %15d\n", i, ip[i], bytes[i]    }}' access.log | sort -t' ' -k2 -rn | head -20 | column -t

案例三:实时监控日志

三剑客配合tail可以实现简单的实时监控:

# 实时监控错误日志tail -f /var/log/app/error.log | grep --line-buffered "ERROR"# 实时统计每秒请求量tail -f access.log | awk '{    count++    if (NR % 100 == 0) {        cmd = "date +%H:%M:%S"        cmd | getline now        close(cmd)        print now, "- Requests in last 100 lines:", count        count = 0    }}'# 实时监控5xx错误tail -f access.log | awk '$9 >= 500 {    print strftime("%Y-%m-%d %H:%M:%S"), "5xx Error:", $7, "Status:", $9    fflush()}'# 实时报警:某IP请求超过阈值tail -f access.log | awk '{    ip[$1]++    if (ip[$1] == 100) {        print "ALERT: IP " $1 " reached 100 requests!"        fflush()    }}'

案例四:多文件关联分析

场景:从多个日志文件中关联分析同一个请求ID:

# 假设request_id在日志中的格式是 [req-xxx-xxx-xxx]# 从access.log找出慢请求的request_idawk '$NF > 5.0 {match($0, /\[req-[a-z0-9-]+\]/, arr); print arr[0]}' \    access.log > slow_request_ids.txt    # 用这些ID从app.log中提取完整日志grep -f slow_request_ids.txt app.log > slow_requests_detail.log# 一行命令完成(管道方式)awk '$NF > 5.0 {match($0, /\[req-[a-z0-9-]+\]/, arr); print arr[0]}' access.log | \    xargs -I {} grep {} app.log

四、最佳实践和注意事项

1、性能优化

经过这些年的实践,我总结了一些提升处理速度的技巧:

1)能用grep过滤的先过滤

这是最重要的原则。如果你只需要处理包含"ERROR"的行,先用grep过滤可以大幅减少后续处理的数据量:

# 慢:awk处理所有行awk '/ERROR/ {print $1}' access.log# 快:先用grep过滤grep "ERROR" access.log | awk '{print $1}'

grep的过滤速度比awk快很多,特别是使用-F(固定字符串)时。

2)使用并行处理

对于大文件,可以用GNU parallel或者xargs实现并行:

# 将大文件分割后并行处理split -l 1000000 access.log chunk_for f in chunk_*; do    awk '{ip[$1]++} END{for(i in ip) print ip[i], i}' "$f" &done | wait | awk '{ip[$2]+=$1} END{for(i in ip) print ip[i], i}' | sort -rn | head -10# 使用GNU parallel(更优雅)cat access.log | parallel --pipe -L 1000000 'awk "{ip[\$1]++} END{for(i in ip) print ip[i], i}"' | \    awk '{ip[$2]+=$1} END{for(i in ip) print ip[i], i}' | sort -rn | head -10# 多文件并行处理ls *.log | parallel -j4 'grep -c ERROR {}'

3)使用ripgrep替代grep

ripgrep(rg)是用Rust写的grep替代品,在大多数场景下都比GNU grep快:

# 安装ripgrep# Ubuntu: apt install ripgrep# macOS: brew install ripgrep# 基本用法rg "ERROR" access.log# 速度对比(1GB日志文件)time grep "ERROR" access.log | wc -l    # 约2.5秒time rg "ERROR" access.log | wc -l      # 约0.8秒# ripgrep独有功能rg -t java "Exception"           # 只搜索Java文件rg --stats "ERROR" access.log    # 显示统计信息rg -C 3 "ERROR" access.log       # 上下文显示rg --json "ERROR" access.log     # JSON输出,便于后续处理

4)避免不必要的排序

sort是性能杀手,尤其是处理大文件时会产生临时文件:

# 如果只需要TOP N,用awk+sort比全排序快# 不好:先排序所有数据sort access.log | uniq -c | sort -rn | head -10# 好:用awk预处理后再排序awk '{count[$1]++} END{for(i in count) print count[i], i}' access.log | sort -rn | head -10

5)使用LC_ALL=C加速

设置LC_ALL=C可以禁用UTF-8处理,大幅提升速度:

# 默认(支持UTF-8)time grep "ERROR" access.log | wc -l# 纯ASCII模式(更快)LC_ALL=C time grep "ERROR" access.log | wc -l# 速度差异可达2-3倍

6)利用mmap和buffer

处理大文件时,调整buffer大小可以提升性能:

# grep使用较大的buffergrep --buffer-size=1M "ERROR" access.log# 使用pv监控处理进度pv access.log | grep "ERROR" | wc -l
2、安全加固

1)永远不要直接在生产环境执行sed -i

# 错误做法sed -i 's/old/new/g' /etc/nginx/nginx.conf# 正确做法cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.backup.$(date +%Y%m%d_%H%M%S)sed -i 's/old/new/g' /etc/nginx/nginx.confnginx -t && systemctl reload nginx || cp /etc/nginx/nginx.conf.backup.* /etc/nginx/nginx.conf

2)处理用户输入时防止命令注入

# 危险:直接拼接用户输入user_input="$1"grep "$user_input" access.log# 安全:使用-F固定字符串,或者转义grep -F "$user_input" access.log# 或者user_input=$(printf '%s' "$1" | sed 's/[[\.*^$()+?{|]/\\&/g')grep "$user_input" access.log

3)限制资源使用

# 限制内存使用ulimit -v 2097152  # 限制为2GB虚拟内存# 限制CPU时间timeout 60 awk '{...}' huge.log# 使用nice降低优先级(不影响线上服务)nice -n 19 awk '{...}' huge.log
3、常见错误

错误1:字段分隔符理解错误

# 问题:默认分隔符是空白字符(空格和Tab),连续空格被当作一个分隔符echo "a  b   c" | awk '{print $2}'  # 输出:b# 如果需要严格按单个空格分隔echo "a  b   c" | awk -F' ' '{print $2}'  # 输出:空(第二个空格)# 处理CSV时常见错误# 错误:字段中有空格会出问题awk -F',' '{print $2}' data.csv# 正确:需要处理引号awk -F',' '{gsub(/"/, ""); print $2}' data.csv

错误2:正则表达式贪婪匹配

# 问题:想匹配第一个引号内的内容echo '"hello" "world"' | grep -oP '".*"'  # 输出:"hello" "world"# 正确:使用非贪婪匹配echo '"hello" "world"' | grep -oP '".*?"'  # 输出:"hello" 和 "world"echo '"hello" "world"' | grep -oP '"[^"]*"'  # 另一种写法

错误3:多行处理的坑

# 问题:想匹配跨行的模式# 这不会工作,因为grep是逐行处理的grep "start.*end" file.log# 正确:使用sed或awk处理多行sed -n '/start/,/end/p' file.logawk '/start/,/end/' file.log# 或者使用grep -z(用NUL作为行分隔符)grep -zoP "start[\s\S]*?end" file.log

错误4:忘记处理特殊字符

# 问题:文件名或内容包含特殊字符# 这会出错grep $variable file.log# 正确:加引号grep "$variable" file.loggrep -- "$variable" file.log  # 如果variable可能以-开头

错误5:awk数值精度问题

# 问题:awk默认的数值精度echo "0.1 0.2" | awk '{print $1 + $2}'  # 可能输出:0.30.30000000000000004# 解决:使用printf控制精度echo "0.1 0.2" | awk '{printf "%.2f\n", $1 + $2}'# 或者使用bc处理高精度计算echo "0.1 + 0.2" | bc -l

五、故障排查和监控

1、日志查看

1)快速定位问题的技巧

# 1. 先看文件大小和时间范围ls -lh *.loghead -1 app.log && tail -1 app.log# 2. 快速统计错误级别分布grep -oP "(DEBUG|INFO|WARN|ERROR|FATAL)" app.log | sort | uniq -c# 3. 查看错误趋势(按小时)grep "ERROR" app.log | awk '{print substr($1, 1, 13)}' | uniq -c# 4. 找出最近10分钟的错误awk -v start=$(date -d '10 minutes ago' +%Y-%m-%dT%H:%M) '$1 > start && /ERROR/' app.log# 5. 随机采样查看shuf -n 100 access.log | less

2)结构化日志处理

现代应用越来越多使用JSON格式日志:

# 提取JSON日志中的特定字段grep "ERROR" app.log | jq -r '.message'# 三剑客配合jq使用awk '/ERROR/' app.log | jq -r '[.timestamp, .level, .message] | @tsv'# 如果没有jq,用grep+sed也能凑合grep "ERROR" app.log | sed 's/.*"message":"\([^"]*\)".*/\1/'# 统计JSON日志中的错误类型grep "ERROR" app.log | grep -oP '"error_type":"\K[^"]+' | sort | uniq -c | sort -rn
2、问题排查

1)常见问题诊断流程

问题1:命令执行很慢

# 诊断:检查文件大小ls -lh target.logwc -l target.log# 诊断:检查是否有复杂正则# 避免使用 .* 这类可能导致回溯的模式# 解决:使用ripgrep或者加LC_ALL=CLC_ALL=C rg "pattern" target.log

问题2:awk结果不正确

# 诊断:打印字段看看是否符合预期head -5 target.log | awk '{for(i=1;i<=NF;i++) print i": "$i}'# 诊断:检查分隔符cat -A target.log | head -1  # 显示不可见字符# 常见原因:# - 文件是DOS格式(行尾有\r)# - 字段分隔符不是空格# - 数据中有意外的空格

问题3:sed替换没生效

# 诊断:先不加-i测试sed 's/old/new/g' file | head -10# 诊断:确认模式能匹配grep "old" file# 常见原因:# - 特殊字符没转义# - 使用了正则表达式元字符# - 原文本包含Tab而非空格

问题4:内存不足

# 诊断:监控内存使用top -b -n 1 | grep awk# 解决方案1:使用更节省内存的方法# 避免把所有数据加载到awk数组# 解决方案2:分片处理split -l 1000000 huge.log part_for f in part_*; do    process "$f" >> result.txtdone# 解决方案3:使用sort的外部排序sort -T /path/to/tmp --buffer-size=1G huge.log
3、监控告警

1)简易的日志监控脚本

#!/bin/bash# log_monitor.sh - 简易日志监控脚本LOG_FILE="/var/log/app/app.log"ALERT_THRESHOLD=10CHECK_INTERVAL=60  # 秒send_alert() {    local message="$1"    # 发送告警(这里用curl调用webhook为例)    curl -X POST "https://your-webhook-url" \        -H "Content-Type: application/json" \        -d "{\"text\": \"$message\"}"}while truedo    # 统计最近1分钟的错误数    start_time=$(date -d '1 minute ago' '+%Y-%m-%d %H:%M')    error_count=$(awk -v start="$start_time" '$1" "$2 >= start && /ERROR/' "$LOG_FILE" | wc -l)    if [ "$error_count" -ge "$ALERT_THRESHOLD" ]; then        send_alert "[ALERT] Error count in last minute: $error_count"    fi        # 检查5xx错误    if [ -f "/var/log/nginx/access.log" ]; then        five_xx=$(tail -10000 /var/log/nginx/access.log | awk '$9 ~ /^5/ {count++} END {print count+0}')        if [ "$five_xx" -ge 50 ]; then            send_alert "[ALERT] High 5xx error rate: $five_xx in last 10k requests"        fi    fi    sleep "$CHECK_INTERVAL"done

2)配合cron的定时分析

# /etc/cron.d/log_analysis# 每小时生成访问统计0 * * * * root /opt/scripts/hourly_log_analysis.sh# 每天凌晨2点生成日报0 2 * * * root /opt/scripts/daily_report.sh# 每5分钟检查错误率*/5 * * * * root /opt/scripts/error_rate_check.sh
#!/bin/bash# hourly_log_analysis.shLOG_FILE="/var/log/nginx/access.log"REPORT_DIR="/var/log/reports"HOUR=$(date -d '1 hour ago' '+%Y%m%d_%H')mkdir -p "$REPORT_DIR"# 提取上一小时的日志hour_pattern=$(date -d '1 hour ago' '+%d/%b/%Y:%H')grep "$hour_pattern" "$LOG_FILE" > "/tmp/hour_${HOUR}.log"# 生成统计报告{    echo "Hourly Report: $HOUR"    echo "========================="    echo ""    echo "Total Requests: $(wc -l < /tmp/hour_${HOUR}.log)"    echo ""    echo "Status Code Distribution:"    awk '{count[$9]++} END{for(s in count) print s, count[s]}' /tmp/hour_${HOUR}.log | sort -k2 -rn    echo ""    echo "Top 10 IPs:"    awk '{print $1}' /tmp/hour_${HOUR}.log | sort | uniq -c | sort -rn | head -10    echo ""    echo "Top 10 URLs:"    awk '{print $7}' /tmp/hour_${HOUR}.log | sort | uniq -c | sort -rn | head -10    echo ""    echo "Top 10 Slowest Requests:"    sort -t' ' -k"$NF" -rn /tmp/hour_${HOUR}.log | head -10} > "${REPORT_DIR}/hourly_${HOUR}.txt"# 清理临时文件rm -f "/tmp/hour_${HOUR}.log"

六、总结

1、要点回顾

经过这些年处理各种日志问题的经验,我总结出以下关键点:

1)选择合适的工具

  • 简单搜索用grep(或ripgrep)

  • 文本替换用sed

  • 复杂统计用awk

  • 三者组合能解决90%的日志处理需求

2)性能优化原则

  • 先过滤再处理(grep在前,awk在后)

  • 使用LC_ALL=C加速纯ASCII处理

  • 大文件考虑并行处理

  • ripgrep通常比grep快3倍以上

3)安全第一

  • 生产环境修改文件必须先备份

  • 用户输入要防止命令注入

  • 资源密集型操作用nice降低优先级

4)调试技巧

  • 先用head测试小数据集

  • 打印中间结果验证每一步

  • 注意分隔符和特殊字符

2、技能提升路径

如果你想在三剑客上更进一步,我建议按这个顺序学习:

1)初级阶段

  • 熟练使用grep的基本参数(-n, -i, -c, -v, -A/B/C)

  • 掌握sed的基本替换和删除操作

  • 学会awk按字段处理数据

2)中级阶段

  • 理解正则表达式的各种模式(贪婪、非贪婪、分组)

  • 掌握sed的多行处理和脚本文件

  • 学会awk的数组和BEGIN/END块

3)高级阶段

  • 深入理解各工具的性能特点,能根据场景选择最优方案

  • 能写复杂的awk程序,包括自定义函数

  • 能把三剑客组合进Shell脚本,实现自动化运维

3、进阶方向

三剑客之外,还有一些现代工具值得关注:

  • **ripgrep (rg)**:Rust写的grep替代品,更快更好用

  • fd:find的现代替代品,语法更友好

  • jq:JSON数据处理利器,处理结构化日志必备

  • miller:CSV/JSON处理工具,比awk更适合处理结构化数据

  • xsv:超快的CSV处理工具

这些工具不是要替代三剑客,而是在特定场景下的补充。核心还是要把grep、sed、awk用熟,它们是所有Linux系统的标配,不需要额外安装。

>>>>

参考资料

  • GNU Grep Manual: https://www.gnu.org/software/grep/manual/

  • GNU Sed Manual: https://www.gnu.org/software/sed/manual/

  • GAWK Manual: https://www.gnu.org/software/gawk/manual/

  • Regular Expressions Info: https://www.regular-expressions.info/

  • ripgrep GitHub: https://github.com/BurntSushi/ripgrep

附录
附录A:命令速查表

grep速查

命令
说明
示例
grep "pattern" file
基本搜索
grep "ERROR" app.log
grep -n
显示行号
grep -n "ERROR" app.log
grep -i
忽略大小写
grep -i "error" app.log
grep -c
统计匹配行数
grep -c "ERROR" app.log
grep -v
反向匹配
grep -v "DEBUG" app.log
grep -l
只显示文件名
grep -l "TODO" *.py
grep -r
递归搜索
grep -r "TODO" ./src
grep -w
全词匹配
grep -w "error" app.log
grep -o
只输出匹配部分
grep -o "ip=[0-9.]*" app.log
grep -A n
显示匹配行后n行
grep -A 5 "Exception" app.log
grep -B n
显示匹配行前n行
grep -B 2 "ERROR" app.log
grep -C n
显示上下文n行
grep -C 3 "FATAL" app.log
grep -E
扩展正则表达式
grep -E "err|warn" app.log
grep -P
Perl正则表达式
grep -P "\d{4}-\d{2}-\d{2}" app.log
grep -F
固定字符串(不解释正则)
grep -F "[ERROR]" app.log
grep --color
高亮匹配
grep --color "ERROR" app.log

sed速查

命令
说明
示例
sed 's/old/new/'
替换第一个匹配
sed 's/error/ERROR/' file
sed 's/old/new/g'
替换所有匹配
sed 's/error/ERROR/g' file
sed 's/old/new/gi'
忽略大小写替换
sed 's/error/ERROR/gi' file
sed -i
原地修改
sed -i 's/old/new/g' file
sed -i.bak
原地修改并备份
sed -i.bak 's/old/new/g' file
sed -n 'p'
只打印匹配行
sed -n '/ERROR/p' file
sed 'd'
删除行
sed '/DEBUG/d' file
sed '10,20d'
删除10-20行
sed '10,20d' file
sed '1,10!d'
只保留1-10行
sed '1,10!d' file
sed 'n1,n2s/.../.../'
指定行范围替换
sed '5,10s/old/new/g' file
sed -e
多个操作
sed -e 's/a/b/' -e 's/c/d/' file
sed -f script
使用脚本文件
sed -f commands.sed file
sed 's/(.*)/[\1]/'
分组引用
给每行加方括号
sed '/pattern/a text'
在匹配行后追加
sed '/EOF/a # End' file
sed '/pattern/i text'
在匹配行前插入
sed '/^$/i # Empty' file
sed '/pattern/c text'
替换整行
sed '/old/c new line' file

awk速查

命令
说明
示例
awk '{print $1}'
打印第一字段
awk '{print $1}' file
awk '{print $NF}'
打印最后字段
awk '{print $NF}' file
awk '{print NR, $0}'
打印行号和整行
awk '{print NR, $0}' file
awk -F:
指定分隔符
awk -F: '{print $1}' /etc/passwd
awk '/pattern/'
模式匹配
awk '/ERROR/' file
awk '$3 > 100'
条件过滤
awk '$3 > 100' file
awk 'NR==1'
指定行号
awk 'NR==1' file
awk 'NR%2==0'
偶数行
awk 'NR%2==0' file
awk 'BEGIN{...}'
处理前执行
awk 'BEGIN{sum=0} ...'
awk 'END{...}'
处理后执行
awk '... END{print sum}'
awk '{sum+=$1}'
累加计算
awk '{sum+=$1} END{print sum}'
awk '{arr[$1]++}'
数组计数
awk '{ip[$1]++} END{...}'
awk '{printf}'
格式化输出
awk '{printf "%10s\n", $1}'
awk 'length($0) > 80'
长度过滤
输出超过80字符的行
awk '{gsub(/old/, "new")}'
替换
awk '{gsub(/http/, "https")}'
awk '{print tolower($1)}'
转小写
awk '{print tolower($1)}'
awk '{print toupper($1)}'
转大写
awk '{print toupper($1)}'
awk '{print substr($1,1,5)}'
子字符串
awk '{print substr($1,1,5)}'
awk '{split($1,arr,"-")}'
分割字符串
按-分割并存入数组
附录B:正则表达式速查

基础元字符

符号
说明
示例
.
匹配任意单个字符
a.c 匹配 abc, adc
*
前一个字符出现0次或多次
ab* 匹配 a, ab, abb
+
前一个字符出现1次或多次(ERE)
ab+ 匹配 ab, abb
?
前一个字符出现0次或1次(ERE)
ab? 匹配 a, ab
^
行首
^Error 匹配行首的Error
$
行尾
error$ 匹配行尾的error
[]
字符类
[abc] 匹配 a, b 或 c
[^]
否定字符类
[^abc] 匹配非a,b,c的字符
|
或(ERE)
cat|dog 匹配cat或dog
()
分组(ERE)
(ab)+ 匹配 ab, abab
{}
重复次数(ERE)
a{2,4} 匹配 aa, aaa, aaaa

PCRE扩展(grep -P)

符号
说明
示例
\d
数字 [0-9]
\d+ 匹配一个或多个数字
\D
非数字
\D+ 匹配非数字字符
\w
单词字符 [a-zA-Z0-9_]
\w+ 匹配单词
\W
非单词字符
\W+ 匹配非单词字符
\s
空白字符
\s+ 匹配空白
\S
非空白字符
\S+ 匹配非空白
\b
单词边界
\berror\b 全词匹配error
(?=)
正向前瞻
foo(?=bar) 匹配后面是bar的foo
(?!)
负向前瞻
foo(?!bar) 匹配后面不是bar的foo
(?:)
非捕获组
(?:ab)+ 分组但不捕获
*?
非贪婪匹配
".*?" 匹配最短的引号内容
附录C:常用组合命令
# 统计IP访问量TOP10awk '{print $1}' access.log | sort | uniq -c | sort -rn | head -10# 统计HTTP状态码分布awk '{print $9}' access.log | sort | uniq -c | sort -rn# 找出响应时间超过5秒的请求awk '$NF > 5' access.log# 统计每小时访问量awk '{split($4, a, ":"); print a[2]}' access.log | sort | uniq -c# 找出5xx错误并统计URLawk '$9 >= 500 {print $7}' access.log | sort | uniq -c | sort -rn | head -10# 提取某时间段的日志awk '$4 >= "[06/Jan/2025:10:00:00" && $4 <= "[06/Jan/2025:11:00:00"' access.log# 统计带宽消耗TOP10 IPawk '{ip[$1]+=$10} END{for(i in ip) print ip[i], i}' access.log | sort -rn | head -10# 分析User-Agent分布awk -F'"' '{print $6}' access.log | sort | uniq -c | sort -rn | head -10# 批量替换文件中的IP地址sed -i 's/192\.168\.1\.1/10.0.0.1/g' *.conf# 删除日志中的敏感信息sed 's/password=[^&]*/password=****/g' app.log# 提取JSON日志中的message字段grep -oP '"message":"\K[^"]+' app.log# 合并多个日志文件并按时间排序cat *.log | sort -k1,2# 实时监控错误日志tail -f app.log | grep --line-buffered "ERROR"# 统计日志文件中的唯一IP数awk '{print $1}' access.log | sort -u | wc -l# 找出包含多个关键词的行grep "ERROR" app.log | grep "database" | grep "timeout"# 提取特定时间范围的错误sed -n '/2025-01-06 10:00/,/2025-01-06 11:00/p' app.log | grep ERROR
附录D:性能基准测试结

测试环境:

  • CPU: Intel Xeon E5-2680 v4 @ 2.40GHz (8核)

  • 内存: 32GB

  • 磁盘: NVMe SSD

  • 日志大小: 10GB(约1亿行)

操作
命令
耗时
备注
简单搜索
grep "ERROR"
28s
基准
简单搜索
rg "ERROR"
9s
3倍加速
简单搜索
LC_ALL=C grep "ERROR"
18s
35%加速
固定字符串
grep -F "ERROR"
12s
比正则快
IP统计
awk '{ip[$1]++}...'
85s
内存峰值1.2GB
IP统计
sort|uniq -c|sort
180s
需要临时文件
统计行数
wc -l
15s
基准
统计行数
awk 'END{print NR}'
45s
慢3倍
响应时间过滤
awk '$NF>5'
90s
全表扫描
响应时间过滤
grep+awk组合
35s
先grep过滤
附录E:术语表
术语
解释
BRE
Basic Regular Expression,基础正则表达式,grep默认模式
ERE
Extended Regular Expression,扩展正则表达式,grep -E模式
PCRE
Perl Compatible Regular Expressions,Perl兼容正则,grep -P模式
NR
Number of Records,awk内置变量,表示当前行号
NF
Number of Fields,awk内置变量,表示当前行的字段数
FS
Field Separator,awk内置变量,字段分隔符
RS
Record Separator,awk内置变量,记录(行)分隔符
OFS
Output Field Separator,awk输出字段分隔符
ORS
Output Record Separator,awk输出记录分隔符
管道
Unix的进程间通信机制,用|符号连接多个命令
流处理
逐行读取和处理数据,不需要将整个文件加载到内存
DFA
Deterministic Finite Automaton,确定性有限自动机,grep使用的正则匹配算法
贪婪匹配
正则表达式默认的匹配模式,尽可能多地匹配字符
非贪婪匹配
使用?修饰符,尽可能少地匹配字符
原地修改
sed -i,直接修改源文件而不是输出到stdout

如果您认为这篇文章有些帮助,还请不吝点下文章末尾的"点赞"和"在看",或者直接转发朋友圈,

可以到各大平台找我,
  • 微信公众号:@bisal的个人杂货铺
  • 腾讯云开发者社区:@bisal的个人杂货铺
  • 头条号:@bisal的个人杂货铺
  • CSDN:@bisal
  • ITPub:@bisal
  • 墨天轮:@bisal
  • 51CTO:@bisal
  • 小红书:@bisal
  • 抖音:@bisal
近期更新的文章:
几个知乎上的精彩回答
sudo启动的进程,到底算不算root启动的进程?
英超第三十二轮
自然语言取代SQL的可能性?
NBA季后赛的对阵
近期Vlog:
千岛湖
Skyline Luge
新疆之行(红山体育馆 - 国际大巴扎 - 红山公园 - 天山天池)
新疆之行(天马浴河 - 哈因塞 - 那拉提 - 依提根塞)
新疆之行(六星街 - 伊昭公路 - 夏塔)
热文鉴赏:
揭开"仿宋"和"仿宋_GB2312"的神秘面纱
Linux的"aarch"是多了个"a"?
中国队“自己的”世界杯
你不知道的C罗-Siu庆祝动作
大阪环球影城避坑指南和功略
推荐一篇Oracle RAC Cache Fusion的经典论文
"红警"游戏开源代码带给我们的震撼
文章分类和索引:
公众号2000篇文章分类和索引

最新文章

随机文章

基本 文件 流程 错误 SQL 调试
  1. 请求信息 : 2026-07-04 09:35:38 HTTP/2.0 GET : https://f.mffb.com.cn/a/488516.html
  2. 运行时间 : 0.163900s [ 吞吐率:6.10req/s ] 内存消耗:5,338.55kb 文件加载:140
  3. 缓存信息 : 0 reads,0 writes
  4. 会话信息 : SESSION_ID=82e46ff3d653267c0003bb52cb560a1d
  1. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/public/index.php ( 0.79 KB )
  2. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/autoload.php ( 0.17 KB )
  3. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/autoload_real.php ( 2.49 KB )
  4. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/platform_check.php ( 0.90 KB )
  5. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/ClassLoader.php ( 14.03 KB )
  6. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/autoload_static.php ( 4.90 KB )
  7. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/helper.php ( 8.34 KB )
  8. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-validate/src/helper.php ( 2.19 KB )
  9. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/helper.php ( 1.47 KB )
  10. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/stubs/load_stubs.php ( 0.16 KB )
  11. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Exception.php ( 1.69 KB )
  12. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-container/src/Facade.php ( 2.71 KB )
  13. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/deprecation-contracts/function.php ( 0.99 KB )
  14. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/polyfill-mbstring/bootstrap.php ( 8.26 KB )
  15. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/polyfill-mbstring/bootstrap80.php ( 9.78 KB )
  16. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/var-dumper/Resources/functions/dump.php ( 1.49 KB )
  17. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-dumper/src/helper.php ( 0.18 KB )
  18. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/var-dumper/VarDumper.php ( 4.30 KB )
  19. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/App.php ( 15.30 KB )
  20. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-container/src/Container.php ( 15.76 KB )
  21. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/container/src/ContainerInterface.php ( 1.02 KB )
  22. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/provider.php ( 0.19 KB )
  23. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Http.php ( 6.04 KB )
  24. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/helper/Str.php ( 7.29 KB )
  25. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Env.php ( 4.68 KB )
  26. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/common.php ( 0.03 KB )
  27. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/helper.php ( 18.78 KB )
  28. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Config.php ( 5.54 KB )
  29. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/app.php ( 0.95 KB )
  30. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/cache.php ( 0.78 KB )
  31. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/console.php ( 0.23 KB )
  32. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/cookie.php ( 0.56 KB )
  33. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/database.php ( 2.48 KB )
  34. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/facade/Env.php ( 1.67 KB )
  35. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/filesystem.php ( 0.61 KB )
  36. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/lang.php ( 0.91 KB )
  37. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/log.php ( 1.35 KB )
  38. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/middleware.php ( 0.19 KB )
  39. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/route.php ( 1.89 KB )
  40. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/session.php ( 0.57 KB )
  41. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/trace.php ( 0.34 KB )
  42. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/view.php ( 0.82 KB )
  43. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/event.php ( 0.25 KB )
  44. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Event.php ( 7.67 KB )
  45. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/service.php ( 0.13 KB )
  46. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/AppService.php ( 0.26 KB )
  47. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Service.php ( 1.64 KB )
  48. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Lang.php ( 7.35 KB )
  49. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/lang/zh-cn.php ( 13.70 KB )
  50. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/initializer/Error.php ( 3.31 KB )
  51. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/initializer/RegisterService.php ( 1.33 KB )
  52. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/services.php ( 0.14 KB )
  53. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/service/PaginatorService.php ( 1.52 KB )
  54. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/service/ValidateService.php ( 0.99 KB )
  55. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/service/ModelService.php ( 2.04 KB )
  56. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-trace/src/Service.php ( 0.77 KB )
  57. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Middleware.php ( 6.72 KB )
  58. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/initializer/BootService.php ( 0.77 KB )
  59. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/Paginator.php ( 11.86 KB )
  60. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-validate/src/Validate.php ( 63.20 KB )
  61. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/Model.php ( 23.55 KB )
  62. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/Attribute.php ( 21.05 KB )
  63. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/AutoWriteData.php ( 4.21 KB )
  64. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/Conversion.php ( 6.44 KB )
  65. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/DbConnect.php ( 5.16 KB )
  66. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/ModelEvent.php ( 2.33 KB )
  67. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/RelationShip.php ( 28.29 KB )
  68. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/contract/Arrayable.php ( 0.09 KB )
  69. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/contract/Jsonable.php ( 0.13 KB )
  70. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/contract/Modelable.php ( 0.09 KB )
  71. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Db.php ( 2.88 KB )
  72. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/DbManager.php ( 8.52 KB )
  73. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Log.php ( 6.28 KB )
  74. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Manager.php ( 3.92 KB )
  75. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/log/src/LoggerTrait.php ( 2.69 KB )
  76. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/log/src/LoggerInterface.php ( 2.71 KB )
  77. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Cache.php ( 4.92 KB )
  78. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/simple-cache/src/CacheInterface.php ( 4.71 KB )
  79. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/helper/Arr.php ( 16.63 KB )
  80. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/cache/driver/File.php ( 7.84 KB )
  81. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/cache/Driver.php ( 9.03 KB )
  82. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/CacheHandlerInterface.php ( 1.99 KB )
  83. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/Request.php ( 0.09 KB )
  84. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Request.php ( 55.78 KB )
  85. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/middleware.php ( 0.25 KB )
  86. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Pipeline.php ( 2.61 KB )
  87. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-trace/src/TraceDebug.php ( 3.40 KB )
  88. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/middleware/SessionInit.php ( 1.94 KB )
  89. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Session.php ( 1.80 KB )
  90. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/session/driver/File.php ( 6.27 KB )
  91. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/SessionHandlerInterface.php ( 0.87 KB )
  92. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/session/Store.php ( 7.12 KB )
  93. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Route.php ( 23.73 KB )
  94. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/RuleName.php ( 5.75 KB )
  95. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/Domain.php ( 2.53 KB )
  96. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/RuleGroup.php ( 22.43 KB )
  97. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/Rule.php ( 26.95 KB )
  98. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/RuleItem.php ( 9.78 KB )
  99. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/route/app.php ( 1.72 KB )
  100. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/facade/Route.php ( 4.70 KB )
  101. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/dispatch/Controller.php ( 4.74 KB )
  102. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/Dispatch.php ( 10.44 KB )
  103. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/controller/Index.php ( 4.81 KB )
  104. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/BaseController.php ( 2.05 KB )
  105. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/facade/Db.php ( 0.93 KB )
  106. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/connector/Mysql.php ( 5.44 KB )
  107. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/PDOConnection.php ( 52.47 KB )
  108. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/Connection.php ( 8.39 KB )
  109. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/ConnectionInterface.php ( 4.57 KB )
  110. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/builder/Mysql.php ( 16.58 KB )
  111. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/Builder.php ( 24.06 KB )
  112. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/BaseBuilder.php ( 27.50 KB )
  113. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/Query.php ( 15.71 KB )
  114. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/BaseQuery.php ( 45.13 KB )
  115. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/TimeFieldQuery.php ( 7.43 KB )
  116. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/AggregateQuery.php ( 3.26 KB )
  117. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/ModelRelationQuery.php ( 20.07 KB )
  118. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/ParamsBind.php ( 3.66 KB )
  119. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/ResultOperation.php ( 7.01 KB )
  120. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/WhereQuery.php ( 19.37 KB )
  121. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/JoinAndViewQuery.php ( 7.11 KB )
  122. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/TableFieldInfo.php ( 2.63 KB )
  123. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/Transaction.php ( 2.77 KB )
  124. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/log/driver/File.php ( 5.96 KB )
  125. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/LogHandlerInterface.php ( 0.86 KB )
  126. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/log/Channel.php ( 3.89 KB )
  127. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/event/LogRecord.php ( 1.02 KB )
  128. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/Collection.php ( 16.47 KB )
  129. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/facade/View.php ( 1.70 KB )
  130. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/View.php ( 4.39 KB )
  131. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Response.php ( 8.81 KB )
  132. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/response/View.php ( 3.29 KB )
  133. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Cookie.php ( 6.06 KB )
  134. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-view/src/Think.php ( 8.38 KB )
  135. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/TemplateHandlerInterface.php ( 1.60 KB )
  136. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-template/src/Template.php ( 46.61 KB )
  137. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-template/src/template/driver/File.php ( 2.41 KB )
  138. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-template/src/template/contract/DriverInterface.php ( 0.86 KB )
  139. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/runtime/temp/067d451b9a0c665040f3f1bdd3293d68.php ( 11.98 KB )
  140. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-trace/src/Html.php ( 4.42 KB )
  1. CONNECT:[ UseTime:0.000605s ] mysql:host=127.0.0.1;port=3306;dbname=f_mffb;charset=utf8mb4
  2. SHOW FULL COLUMNS FROM `fenlei` [ RunTime:0.000885s ]
  3. SELECT * FROM `fenlei` WHERE `fid` = 0 [ RunTime:0.000320s ]
  4. SELECT * FROM `fenlei` WHERE `fid` = 63 [ RunTime:0.000283s ]
  5. SHOW FULL COLUMNS FROM `set` [ RunTime:0.000519s ]
  6. SELECT * FROM `set` [ RunTime:0.000207s ]
  7. SHOW FULL COLUMNS FROM `article` [ RunTime:0.000579s ]
  8. SELECT * FROM `article` WHERE `id` = 488516 LIMIT 1 [ RunTime:0.000846s ]
  9. UPDATE `article` SET `lasttime` = 1783128938 WHERE `id` = 488516 [ RunTime:0.011008s ]
  10. SELECT * FROM `fenlei` WHERE `id` = 67 LIMIT 1 [ RunTime:0.007237s ]
  11. SELECT * FROM `article` WHERE `id` < 488516 ORDER BY `id` DESC LIMIT 1 [ RunTime:0.009139s ]
  12. SELECT * FROM `article` WHERE `id` > 488516 ORDER BY `id` ASC LIMIT 1 [ RunTime:0.019781s ]
  13. SELECT * FROM `article` WHERE `id` < 488516 ORDER BY `id` DESC LIMIT 10 [ RunTime:0.018690s ]
  14. SELECT * FROM `article` WHERE `id` < 488516 ORDER BY `id` DESC LIMIT 10,10 [ RunTime:0.014775s ]
  15. SELECT * FROM `article` WHERE `id` < 488516 ORDER BY `id` DESC LIMIT 20,10 [ RunTime:0.006640s ]
0.165454s