酒吧点餐业务实践:线下酒馆自助点单系统实现思路
2026/10/1 8:03:31
bash
cat > /tmp/test.log <<'EOF' 2024-01-15 10:23:45 ERROR [user-service] Failed to login: user=alice ip=192.168.1.10 2024-01-15 10:24:01 INFO [user-service] User login success: user=bob ip=192.168.1.11 2024-01-15 10:25:12 ERROR [order-service] Payment timeout: order=1001 amount=99.9 2024-01-15 10:26:33 WARN [order-service] Retry payment: order=1001 attempt=2 2024-01-15 10:27:45 INFO [order-service] Payment success: order=1001 amount=99.9 2024-01-15 10:28:10 ERROR [user-service] Failed to login: user=alice ip=192.168.1.10 2024-01-15 10:29:55 DEBUG [cache-service] Cache hit ratio: 0.85 EOF
bash
# 查找 ERROR 行 grep "ERROR" /tmp/test.log # 忽略大小写 grep -i "error" /tmp/test.log # 显示行号 grep -n "ERROR" /tmp/test.log # 反向匹配(不包含) grep -v "INFO" /tmp/test.log # 统计匹配行数 grep -c "ERROR" /tmp/test.log
bash
# 扩展正则(-E),匹配 ERROR 或 WARN grep -E "ERROR|WARN" /tmp/test.log # 匹配多个关键字(与) grep "ERROR" /tmp/test.log | grep "alice" # 只输出匹配部分 grep -oE "user=[a-z]+" /tmp/test.log # 递归查找目录 grep -rn "ERROR" /var/log/
bash
# 上下文(前2行后3行) grep -B2 -A3 "Payment timeout" /tmp/test.log # 只列出文件名 grep -l "ERROR" *.log # 静默模式(脚本中判断是否存在) if grep -q "ERROR" /tmp/test.log; then echo "有错误"; fi
bash
# 替换第一个匹配 sed 's/ERROR/ERR/' /tmp/test.log # 全局替换 sed 's/ERROR/ERR/g' /tmp/test.log # 直接修改文件(-i) sed -i 's/ERROR/ERR/g' /tmp/test.log sed -i.bak 's/ERROR/ERR/g' /tmp/test.log # 备份 # 指定行范围替换 sed '1,3s/INFO/INFORMATION/' /tmp/test.log # 只替换匹配行的内容(先定位再替换) sed '/alice/s/192.168.1.10/10.0.0.1/' /tmp/test.log
bash
# 删除第 3 行 sed '3d' /tmp/test.log # 删除 2-4 行 sed '2,4d' /tmp/test.log # 删除包含 DEBUG 的行 sed '/DEBUG/d' /tmp/test.log # 删除空行 sed '/^$/d' /tmp/test.log # 删除行尾空白 sed 's/[[:space:]]*$//' /tmp/test.log
bash
# 在第 1 行前插入 sed '1i\=== LOG START ===' /tmp/test.log # 在匹配行后追加 sed '/ERROR/a\>>> 需要关注 <<<' /tmp/test.log # 替换整行 sed '/DEBUG/c\DEBUG 行已被替换' /tmp/test.log
bash
# 只打印匹配行(-n 抑制默认输出) sed -n '/ERROR/p' /tmp/test.log # 打印 2-4 行 sed -n '2,4p' /tmp/test.log # 打印最后一行 sed -n '$p' /tmp/test.log
bash
# 提取 user=xxx sed -n 's/.*user=\([a-z]*\).*/\1/p' /tmp/test.log # 提取 IP sed -n 's/.*ip=\([0-9.]*\).*/\1/p' /tmp/test.log
bash
# 打印第 1、3 列(默认空格分隔) awk '{print $1, $3}' /tmp/test.log # 打印整行 awk '{print $0}' /tmp/test.log # 指定分隔符(-F) awk -F'=' '{print $1}' /tmp/test.log # 打印行号 + 内容 awk '{print NR": "$0}' /tmp/test.log # 打印最后一列 awk '{print $NF}' /tmp/test.logbash
# 打印 ERROR 行 awk '/ERROR/' /tmp/test.log # 打印第 3 列是 ERROR 的行 awk '$3=="ERROR"' /tmp/test.log # 多个条件 awk '$3=="ERROR" && $4 ~ /user-service/' /tmp/test.log # 数值比较 awk '$1 > 100' data.txt # 取反 awk '$3!="INFO"' /tmp/test.log
bash
# 统计 ERROR 行数 awk '/ERROR/{count++} END{print count}' /tmp/test.log # 按日志级别统计 awk '{level[$3]++} END{for (l in level) print l, level[l]}' /tmp/test.log # 求和 awk '{sum+=$NF} END{print sum}' numbers.txt # 求平均 awk '{sum+=$1; n++} END{print sum/n}' numbers.txt # 求最大/最小值 awk 'NR==1{max=$1} $1>max{max=$1} END{print max}' numbers.txtbash
# BEGIN/END 块 awk 'BEGIN{print "=== 结果 ==="} {print $1} END{print "=== 结束 ==="}' /tmp/test.log # printf 格式化 awk '{printf "%-10s %s\n", $3, $1}' /tmp/test.log # 指定输出分隔符 awk 'BEGIN{OFS="|"} {print $1, $3, $4}' /tmp/test.logbash
# 提取 IP 并统计出现次数 awk '{for(i=1;i<=NF;i++) if($i ~ /ip=/){gsub("ip=","",$i); print $i}}' /tmp/test.log | sort | uniq -c # 按服务统计 ERROR 数量 awk '/ERROR/{gsub(/\[|\]/,"",$4); svc[$4]++} END{for(s in svc) print s, svc[s]}' /tmp/test.log # 打印每行字段数 awk '{print NR, NF}' /tmp/test.logbash
grep "ERROR" /tmp/test.log | awk '{print $4}' | sed 's/\[//;s/\]//' | sort | uniq -c | sort -rnbash
grep "Payment timeout" /tmp/test.log | awk '{for(i=1;i<=NF;i++){if($i~/^order=/)o=$i; if($i~/^amount=/)a=$i} print o, a}'bash
awk '{print $1","$2","$3","$4}' /tmp/test.log > /tmp/test.csvbash
grep "Failed to login" /tmp/test.log | sed -n 's/.*user=\([a-z]*\).*/\1/p' | sort | uniq -c | sort -rn
bash
sed -i -E 's/ip=[0-9.]+/ip=***.***.***.***/g' /tmp/test.log
bash
awk '{print substr($2,1,2)}' /tmp/test.log | sort | uniq -c| 需求 | 推荐 |
|---|---|
| 找行 / 过滤 | grep |
| 替换 / 删除行 / 插入 | sed |
| 按列处理 / 统计 / 计算 | awk |
| 找行后替换 | grep + sed |
| 找行后按列统计 | grep + awk |
| 复杂分析 | awk 单独搞定 |
核心记忆:
grep =查
sed =改(行级)
awk =算(列级)