aixingpan.cn API开发文档:api_docs_bichart_natalvssecondary2接口指南
2026/10/2 8:34:36
sed(Stream Editor) 的核心思想是:逐行读取 → 匹配模式 → 执行操作。它不修改源文件(除非加-i),而是将处理结果输出到标准输出。基本语法:bashsed [选项] '地址范围操作' 文件### 2.2 场景 1:批量替换 Nginx 配置中的域名nginx# 旧的 nginx.confserver_name old-domain.com;# 要把所有 old-domain.com 替换为 new-domain.com解法:bashsed -i 's/old-domain\.com/new-domain.com/g' nginx.conf````-i` 是直接修改源文件,`s` 是替换命令,`g` 是全局替换(每一行所有匹配位置,不止第一处)。**⚠️ 生产环境安全写法:**bash# 先备份再修改sed -i.bak ‘s/old/new/g’ config.conf# 这样会生成 config.conf.bak 作为备份### 2.3 场景 2:删除日志中的特定行假设你要清理 `access.log` 中的健康检查请求(来自 k8s 的 `/healthz` 端点):bash# 删除包含 /healthz 的行sed ‘//healthz/d’ access.log > clean.log````d是删除命令。多个模式可以用-e:```bashsed -e '/\/healthz/d' -e '/\/metrics/d' access.log > clean.log```### 2.4 场景 3:只打印某个区间的行```bash# 打印第 10 到第 20 行sed -n '10,20p' file.log# -n 选项:不自动打印(只打印匹配的行)# p 命令:打印匹配的行```### 2.5 场景 4:在匹配行前后插入内容```bash# 在包含 [server] 的行之前插入一行sed '/\[server\]/i\# Server Configuration' config.ini# 在包含 [server] 的行之后追加一行sed '/\[server\]/a\timout = 30' config.ini```### 2.6 sed 的高级文本替换```bash# 引用匹配内容(反向引用)echo 'hello=world' | sed 's/\([^=]*\)=\(.*\)/\2 = \1/'# 输出: world = hello# 多模式替换sed -e 's/ERROR/INFO/g' -e 's/WARN/INFO/g' app.log# 只替换每行第二次出现的匹配sed 's/,/|/2' data.csv # 每行第二个逗号换成 |```**📌 核心口诀:**s/旧/新/基础替换,g全局替换,-i直接写文件,-n p只打印匹配行。---## 三、awk — 文本分析器:结构化数据处理### 3.1 awk 的核心哲学awk的理念更接近数据库查询:**把文本当表格,行是记录,列是字段**,你可以按字段筛选、计算、格式化输出。基本语法:```bashawk [选项] 'BEGIN{前置命令} 条件 {行处理命令} END{后置命令}' 文件```每个字段用$1,$2, ... 引用,$0代表整行。默认字段分隔符是空白(空格/Tab)。### 3.2 场景 5:分析 access.log 统计各 IP 的访问量这是运维中最经典的需求:```bash# 假设日志格式:IP - - [日期] "请求" 状态码 大小# 192.168.1.1 - - [28/Jun/2026:10:00:00 +0800] "GET /api HTTP/1.1" 200 1234awk '{count[$1]++} END {for (ip in count) print ip, count[ip]}' access.log | sort -k2 -rn | head -10```**分解:**-{count[$1]++}— 以第1列(IP)为键,每出现一次计数+1-END {…}— 文件处理完后执行-for…— 遍历字典,输出 IP 和计数-sort -k2 -rn— 按第二列(计数)逆序排序-head -10— 取前 10### 3.3 场景 6:筛选出 5xx 错误并格式化输出```bashawk '$9 ~ /^5[0-9][0-9]$/ {printf "%-20s %-15s %s\n", $4, $1, $9}' access.log```输出:```[28/Jun/2026:10:00 192.168.1.1 500[28/Jun/2026:10:01 10.0.0.5 502```**解释:**-$9 ~ /^5…/— 第9列匹配 5xx 状态码-printf— 格式化输出,%-20s左对齐占20字符### 3.4 场景 7:CSV 文件数据提取与计算```csv# employees.csvname,department,salary,years张三,技术部,15000,3李四,技术部,18000,5王五,市场部,12000,2赵六,市场部,14000,4```**统计各部门平均工资:**```bashawk -F, 'NR>1 {dept[$2]+=$3; count[$2]++} END {for (d in dept) printf "%s: %.2f (共%d人)\n", d, dept[d]/count[d], count[d]}' employees.csv```输出:```市场部: 13000.00 (共2人)技术部: 16500.00 (共2人)```**关键点:**--F,— 指定逗号为字段分隔符-NR>1— 跳过标题行(NR:当前行号)### 3.5 场景 8:日志时间范围过滤```bash# 筛选 10:00 到 10:59 之间的日志awk '$4 ~ /^\[28\/Jun\/2026:10:/' access.log```### 3.6 awk 内置变量速查| 变量 | 含义 ||:----|:----||NR| 已读取的记录数(行号) ||NF| 当前行的字段数(列数) ||$0| 整行内容 ||1..1..1..n| 第 1~n 个字段 ||FS| 字段分隔符(默认空白) ||OFS| 输出字段分隔符(默认空格) ||RS| 记录分隔符(默认换行) |**📌 核心口诀:**$1$2取字段,{c[KaTeX parse error: Expected 'EOF', got '}' at position 5: 1]++}̲` 做统计,`printf` …(wc -l < “$LOG_FILE”)echo “总请求数: $total”# 2. 状态码分布echo -e "\n— 状态码分布 —“awk '{codes[KaTeX parse error: Expected 'EOF', got '}' at position 5: 9]++}̲ END {for (c in…LOG_FILE” | sort -k2 -rn# 3. 最活跃的前 10 个 IPecho -e “\n— 最活跃 IP Top 10 —“awk '{ips[KaTeX parse error: Expected 'EOF', got '}' at position 5: 1]++}̲ END {for (i in…LOG_FILE” | sort -rn | head -10 | awk '{printf " %-20s %d次\n”, $2, $1}‘# 4. 请求最多的 URL Top 10echo -e “\n— 最热 URL Top 10 —“awk '{url=KaTeX parse error: Undefined control sequence: \? at position 10: 7; gsub(/\̲?̲.*/, "", url); …LOG_FILE” | sort -rn | head -10 | awk '{printf " %-50s %d次\n”, $2,KaTeX parse error: Expected 'EOF', got '}' at position 2: 1}̲'# 5. 4xx/5xx 错…(awk ‘9 /[45][0−9][0−9]9 ~ /^[45][0-9][0-9]9/[45][0−9][0−9]/’ “$LOG_FILE” | wc -l)echo -e "\n— 错误分析 —"echo " 4xx/5xx 错误数: $errors"echo " 错误率: $(echo “scale=2; $errors * 100 /total"∣bc)total" | bc)%"```### 5.2 场景 12:配置文件中批量修改参数```bash#!/bin/bash# update_config.sh — 批量修改配置文件CONFIG="/etc/myapp/config.ini"# sed 批量修改sed -i.bak \ -e 's/^debug=false/debug=true/' \ -e 's/^port=8080/port=9090/' \ -e '/^#.*database_url/s/^#//' \ "total"∣bc)CONFIG”# awk 校验修改结果echo "=== 修改后的关键配置 ===“awk -F= ‘/^(debug|port|database_url)/’ “$CONFIG”```### 5.3 场景 13:多文件数据合并与分析```bash# 合并多个服务器上的日志,统计按小时的请求分布cat server1.log server2.log server3.log | \ awk ‘{split($4, arr, /[/:]/); hour=arr[5]} {hourly[hour]++} END {for (h in hourly) printf “%02d:00 → %d次\n”, h, hourly[h]}’ | \ sort```### 5.4 场景 14:实时监控与报警```bash#!/bin/bash# monitor_5xx.sh — 实时监控 5xx 错误并报警tail -f /var/log/nginx/access.log | \ awk ‘9 /5[0−9][0−9]9 ~ /^5[0-9][0-9]9/5[0−9][0−9]/ { system("echo “[ALERT] 5xx错误: " $0 “” | mail -s “告警: Nginx 5xx错误” admin@example.com”) printf “🔴 [%s] 5xx错误: %s %s\n”, $4, $1, $9 }’```—## 六、性能与效率对比| 场景 | sed | awk | grep | 推荐 ||:----|:—😐:—😐:—😐:----:|| 简单替换 | ⭐⭐⭐ | ⭐⭐ | — |sed|| 删除特定行 | ⭐⭐⭐ | ⭐⭐ | — |sed|| 统计聚合 | — | ⭐⭐⭐ | — |awk|| 字段筛选 | — | ⭐⭐⭐ | — |awk|| 正则搜索 | ⭐⭐ | ⭐⭐ | ⭐⭐⭐ |grep|| 上下文显示 | ⭐ | — | ⭐⭐⭐ |grep -C|| 复杂数据管道 | ⭐ | ⭐⭐⭐ | ⭐ |awk + pipe|| 处理大文件(>1GB) | ⭐⭐⭐ | ⭐⭐ | ⭐⭐⭐ |sed/grep|经验之谈:能用 grep 解决的问题不要用 sed,能用 sed 解决的不要用 awk。工具越专用效率越高。但当任务复杂到需要"算"的时候,awk 是最趁手的。—## 七、常见的坑与避坑指南### 7.1 sed 中的正则转义```bash# ❌ 错误:特殊字符未转义sed ‘s/old.com/new.com/g’ file # . 会匹配任意字符# ✅ 正确:转义点号sed ‘s/old.com/new.com/g’ file# 或者用扩展正则 (-E)sed -E ‘s/old.com/new.com/g’ file```### 7.2 awk 中的 shell 变量传递```bash# ❌ 错误:shell 变量直接在 awk 中使用keyword=“ERROR"awk ‘0 /0 ~ /0/keyword/’ log # awk 不识别KaTeX parse error: Expected 'EOF', got '#' at position 8: keyword#̲ ✅ 正确:使用 -v 传递变…keyword” ‘$0 ~ kw/’ log# 或者用单引号跳转awk '0 /′"0 ~ /'"0/′"keyword”’/’ log```### 7.3 大文件处理```bash# 处理超大文件时,用管道避免中间文件# ❌ 差:先 grep 写入中间文件grep “ERROR” huge.log > errors.logawk ‘{count[$1]++} END {for …}’ errors.log# ✅ 好:管道直接传递grep “ERROR” huge.log | awk ‘{count[$1]++} END {for …}’```—## 八、总结| 工具 | 说人话 | 最擅长 ||:----|:------|:-------||grep| 文本搜索器 | 在文件堆里找东西 ||sed| 文本手术刀 | 批量替换、增删行 ||awk| 文本数据库 | 按列分析、统计、格式化 |这三把剑组合起来,你在 Linux 下的文本处理能力就基本毕业了。下次遇到任何文本处理任务,先问自己三个问题:1. 要找人→grep2. 要改东西→sed 3. 要算数据→awk—下一篇预告:Shell 调试技巧——告别脚本报错找不到原因