当前位置:首页>Linux>Linux Shell 三剑客中级指南

Linux Shell 三剑客中级指南

  • 2026-10-06 15:37:43
Linux Shell 三剑客中级指南

适用人群:已掌握三剑客基础用法,希望进阶生产环境实战的运维/开发工程师目标:从“能写脚本”到“能高效处理大规模日志、能优化性能、能解决复杂文本问题”

一、三剑客核心定位与选型

工具
核心定位
适用场景
处理方式
grep
文本过滤
快速查找匹配行、统计出现次数
逐行匹配,返回匹配行
sed
文本编辑
替换、删除、插入、格式转换
流式编辑,非交互
awk
文本分析与报表
字段提取、统计计算、数据格式化
行处理 + 字段分割 + 编程逻辑

生产环境选型铁律:grep 做“筛选”,sed 做“替换”,awk 做“分析”。三者常组合使用,形成“grep 过滤 → sed 清洗 → awk 统计”的流水线。

二、grep 中级精进

2.1 常用选项速查

选项
含义
生产场景
-E
扩展正则
替代 egrep,支持 |、+、?、{n,m}
-P
Perl 正则(GNU grep)
支持 \d、\w、s、lookahead
-o
只输出匹配部分
提取 IP、邮箱、URL
-c
统计匹配行数
快速统计日志错误数量
-A n / -B n / -C n
输出上下文行
查看错误前后日志
-l / -L
列出匹配/不匹配的文件名
批量查找包含关键字的文件
-r / -R
递归搜索目录
全目录代码/日志扫描
--exclude
 / --include
过滤搜索文件类型
只搜索 .log,跳过 .gz

2.2 正则表达式进阶

字符类简写:

bash

\d    # 数字   → [0-9]\w    # 单词   → [A-Za-z0-9_]\s    # 空白   → [ \t\n\r\f\v]\D \W \S # 对应反义

量词与分组:

bash

{n,m}# 出现 n 到 m 次+       # 1 次或多次(等于 {1,})?       # 0 次或 1 次(等于 {0,1})(...)# 捕获分组,后面可用 \1 引用

零宽断言(Perl 正则):

bash

(?=pattern)# 正向先行断言:后面跟着 pattern(?!pattern)# 负向先行断言:后面不跟着 pattern(?<=pattern)# 正向后行断言:前面是 pattern(?<!pattern)# 负向后行断言:前面不是 pattern

2.3 生产实战示例

提取 Nginx 日志中的真实客户端 IP(含代理链):

bash

grep-oP'(?<![0-9.])[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+(?![0-9.])' access.log |head-5

快速统计日志中某个错误码在每小时的分布(正则截取日期+提取数据):

bash

grep-E'ERROR|FATAL' app.log |grep-o'2026-08-12 [0-9]{2}:00'|sort|uniq-c

在 /var/log 下递归查找所有包含 Out of memory 的 *.log 文件:

bash

grep-rl--include="*.log""Out of memory" /var/log/

从混合日志中同时提取多个模式的上下文(且忽略大小写):

bash

grep-E-i'panic|fatal|segfault'-C5 app.log

三、sed 中级精进

3.1 常用命令与寻址

基本语法:sed [options] 'command' file

命令
含义
s/old/new/
替换(默认仅替换每行第一个)
s/old/new/g
全局替换
s/old/new/2
替换每行第 2 个匹配
s/old/new/p
替换并打印(常与 -n 搭配)
d
删除匹配行
p
打印(配合 -n)
a
 / i
行后插入 / 行前插入
c
替换整行
n
读取下一行(多行处理)
N
追加下一行到模式空间(多行替换)
y/source/dest/
字符转换
r
 / w
读文件 / 写文件
q
退出(提前终止)
=
打印行号

寻址方式:

bash

sed-n'5p'file# 打印第 5 行sed-n'5,10p'file# 打印 5-10 行sed'5,10d'file# 删除 5-10 行sed'/error/d'file# 删除包含 error 的行sed'/start/,/end/p'# 从匹配 start 的行到匹配 end 的行

3.2 分组与反向引用(核心中级技能)

bash

# 将 2026-08-12 改为 08/12/2026sed-E's/([0-9]{4})-([0-9]{2})-([0-9]{2})/\2\/\3\/\1/g'file

在 sed 中,用 \( \) 捕获(基础正则)或 ( )(扩展正则 -E),用 \1、\2 引用。

匹配难度较大的 & 引用(取整行匹配):

bash

echo"hello world"|sed-E's/[a-z]+/[\&]/g'# 输出:[hello] [world]

3.3 高级编辑模式

  • 模式空间(Pattern Space):sed 默认的处理缓冲区,逐行读入并执行命令

  • 保持空间(Hold Space):辅助缓冲区,用于跨行数据的暂存

交换保持空间与模式空间(x)、追加保持空间到模式空间(G):

bash

# 反转文件行序(tac 的 sed 实现)sed'1!G;h;$!d'file

多行替换(处理跨行):

bash

# 将跨行的 <tag>...</tag> 合并为一行sed-n'/<tag>/{:a;N;/<\/tag>/!ba;s/\n/ /g;p}'file

3.4 生产实战示例

批量替换配置文件中所有 localhost 为 127.0.0.1,仅替换前 5 个匹配项:

bash

sed-i's/localhost/127.0.0.1/5' config.ini

从 /etc/passwd 中提取用户名和家目录(打印第 1 和第 6 字段),并删除以 # 开头的注释行与空白行:

bash

sed-E-e'/^#/d'-e'/^$/d'-e's/^([^:]+):.*:([^:]+)$/\1 \2/' /etc/passwd

将 JSON 日志中的 ISO 8601 时间戳 2026-08-12T14:30:00Z 替换为 Unix 时间戳:

bash

# 使用 date 命令配合 sed 的 e 修饰符(GNU sed)sed-E's/([0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z)/'"$(date-d'\1' +%s)"'/g' file

四、awk 中级精进

4.1 核心执行模型

text

BEGIN{...} → 逐行处理 → END{...}

每行处理:自动按 FS(字段分隔符)分割成 $1...$NF,$0 为整行,NR 为行号,NF 为字段数。

4.2 常用变量与选项

变量/选项
含义
-F
指定字段分隔符,如 -F,、-F'[ :]+'
FS
输入分隔符
OFS
输出分隔符(默认空格)
RS
记录分隔符(默认换行)
ORS
输出记录分隔符
NR
当前行号
NF
当前行字段数
$0
整行内容
$n
第 n 个字段

4.3 内置函数(中级必备)

字符串函数:

bash

length($0)# 字符串长度substr($1, 2, 3)# 子串(从第2位开始取3位)split($0, arr, ",")# 分割成数组 arrindex($1, "abc")# 返回子串位置toupper($1) / tolower($1)

数学函数:

bash

sqrt($1)# 平方根int($1)# 取整rand()# 随机数(需先 srand())

时间函数:

bash

systime()# 当前 Unix 时间戳strftime("%Y-%m-%d", systime())

4.4 数组与循环

bash

# 关联数组(统计 IP 访问量)awk'{count[$1]++} END {for(ip in count) print ip, count[ip]}' access.log# 遍历数组的两种方式for(key in array){... }# 无序for(i=1; i<=length(array); i++){}# 有序(需额外处理)# 删除数组元素delete array[key]

4.5 生产实战示例

分析 Nginx 访问日志,统计每个状态码的数量、最大响应时间、平均响应时间:

bash

awk'{code=$9; time=$10; total[code]++; sum[code]+=time; if(time>max[code]) max[code]=time}     END {for(c in total) printf "%s: count=%d avg=%.2f max=%.2f\n", c, total[c], sum[c]/total[c], max[c]}' access.log

处理多行日志(如 Java 堆栈,RS 设为空行):

bash

awk'BEGIN{RS=""; FS="\n"} /OutOfMemoryError/{print "==== Stack Trace ====\n" $0}' app.log

合并两个文件(类似 JOIN):

bash

# user.csv: id,name# order.csv: user_id,order_id,amountawk -F, 'NR==FNR{a[$1]=$2; next} {print $0, a[$1]}' user.csv order.csv

从大量 JSON 格式的日志中提取 latency 字段并输出到 CSV:

bash

grep'"level":"ERROR"' app.log |awk -F'"''{for(i=1;i<=NF;i++) if($i=="latency") print $(i+2)}'|sort-n|head-10

五、三剑客协同作战

5.1 标准流水线

bash

# 1. 用 grep 快速过滤出 ERROR 级别日志# 2. 用 sed 清洗不需要的字段、去掉时间戳# 3. 用 awk 按接口聚合统计grep'ERROR' app.log \|sed-E's/^[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2} //'\|awk -F'|''{count[$2]++; sum[$2]+=$4} END{for(i in count) print i, count[i], sum[i]/count[i]}'

5.2 性能分层原则

任务
推荐工具
原因
行匹配/过滤
grep
速度最快,C 实现
简单替换/删除
sed
比 awk 轻量,无字段分割开销
字段提取/统计
awk
内置字段分割和数组
复杂逻辑
Python/Perl
可维护性更好

黄金公式:grep 处理“有无”问题,sed 处理“要不要”问题,awk 处理“有多少”问题。

5.3 大文件优化技巧

bash

# 使用 LC_ALL=C 禁用字符集处理,加速 grepLC_ALL=C grep'pattern' bigfile# 优先过滤再处理(减少 awk 处理的行数)awk'/ERROR/{...}' bigfile.log   # 等价但不如 grep 快grep'ERROR' bigfile.log |awk'{...}'# 更快# 使用 mmap 读取(部分 awk 版本支持)awk-V|grep-i'gawk'# GNU awk 支持大文件更友好

六、常见陷阱与避坑指南

陷阱
正确做法
grep -v
 删除空行时误删关键行
使用 grep -v '^$' 或 awk 'NF'
sed 替换时正则中的 / 未转义
更换分隔符:sed 's#a/b#c/d#g'
awk 中 $NF 当作变量 vs 字符串
$NF
 是最后一个字段,"$NF" 是字符串
awk 中数组遍历顺序随机
用 asorti() 或管道传递给 sort
忘记处理文件编码(如 GBK vs UTF-8)
先用 file 或 iconv 转换编码
sed -i
 在 Mac 上需要指定备份后缀
使用 sed -i ''(BSD sed)

七、总结与能力阶定位

水平
grep 能力
sed 能力
awk 能力
初级
会用 grep -E 'pattern'
基本替换 s/old/new/g
会提取 $1、$NF
中级(本指南目标)
会用 -P、-o、上下文、递归
分组反向引用、保持空间、多行处理
数组统计、函数、多文件关联
高级
大规模日志性能优化
复杂编辑流程自动化
深度脚本化(类似编程语言)

掌握三剑客的核心在于把复杂的文本问题拆解成“筛选 → 清洗 → 统计”三个步骤,然后选用合适的工具完成。持续练习日志分析、配置管理、监控脚本这三个典型场景,技能会快速提升。

最新文章

随机文章