> Linux文本处理三剑客:grep、sed、awk实战

为什么叫"三剑客"

grep、sed、awk被称为Linux文本处理三剑客,因为它们各有所长:

工具擅长领域一句话总结
grep搜索/过滤找出包含关键词的行
sed替换/编辑对文本做查找替换
awk分析/统计按列处理和统计数据

服务器运维中,日志分析、配置修改、数据提取都离不开这三个工具。我几乎每天都在用。

grep:文本搜索

基本用法

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
# 在文件中搜索关键词
$ grep "error" /var/log/syslog
Jan 17 10:01:23 server kernel: [error] something went wrong
Jan 17 10:05:45 server nginx: 2026/01/17 10:05:45 [error] 1234#0

# 忽略大小写
$ grep -i "error" /var/log/syslog

# 显示行号
$ grep -n "error" /var/log/syslog
142:Jan 17 10:01:23 server kernel: [error] something went wrong
256:Jan 17 10:05:45 server nginx: 2026/01/17 10:05:45 [error] 1234#0

# 显示匹配行的前后几行
$ grep -C 3 "error" /var/log/syslog  # 前后各3行
$ grep -B 2 "error" /var/log/syslog  # 前2行
$ grep -A 2 "error" /var/log/syslog  # 后2行

常用参数

参数功能示例
-i忽略大小写grep -i "error" log
-n显示行号grep -n "error" log
-r递归搜索grep -r "TODO" /src/
-v反向匹配grep -v "debug" log
-c统计匹配行数grep -c "error" log
-l只显示文件名grep -rl "error" /var/log/
-E使用正则`grep -E “error

实战示例

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
# 查找Nginx的404错误
$ grep "\" 404" /var/log/nginx/access.log
203.0.113.5 - - [17/Jan/2026:10:00:00 +0000] "GET /notfound HTTP/1.1" 404 162

# 统计每种HTTP状态码的数量
$ grep -oP '\" \K\d{3}' /var/log/nginx/access.log | sort | uniq -c | sort -rn
   1523 200
    234 301
     89 404
     12 500

# 递归搜索代码中的TODO
$ grep -rn "TODO" /var/www/myproject/ --include="*.py"
/var/www/myproject/app.py:45:    # TODO: 添加错误处理
/var/www/myproject/utils.py:12:  # TODO: 优化性能

sed:流编辑器

基本替换

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
# 替换第一个匹配项
$ echo "hello world" | sed 's/hello/hi/'
hi world

# 替换所有匹配项(加g标志)
$ echo "aaa bbb aaa" | sed 's/aaa/ccc/g'
ccc bbb ccc

# 直接修改文件(-i参数)
$ sed -i 's/old_text/new_text/g' config.txt

# 安全的做法:先备份再修改
$ sed -i.bak 's/old_text/new_text/g' config.txt
# 会自动创建config.txt.bak备份

常用操作

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
# 删除包含关键词的行
$ sed -i '/pattern/d' file.txt

# 删除空行
$ sed -i '/^$/d' file.txt

# 在第3行后插入内容
$ sed -i '3a\新的一行内容' file.txt

# 在第3行前插入内容
$ sed -i '3i\新的一行内容' file.txt

# 只处理第5到10行
$ sed -n '5,10p' file.txt

# 替换某一行的内容
$ sed -i '5s/.*/新的第5行内容/' file.txt

实战示例

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
# 修改Nginx配置中的端口
$ sed -i 's/listen 80;/listen 8080;/g' /etc/nginx/sites-available/default

# 批量修改配置文件中的IP
$ sed -i 's/192.168.1.100/10.0.0.50/g' /etc/nginx/conf.d/*.conf

# 去掉配置文件中的注释行
$ sed '/^#/d; /^$/d' /etc/nginx/nginx.conf
# 只显示有效配置,不修改文件(没有-i)

# 在配置文件特定位置插入内容
$ sed -i '/server_name/a\    proxy_set_header Host $host;' /etc/nginx/conf.d/mysite.conf

awk:数据分析

基本用法

awk按列处理数据,默认以空格/Tab分隔。

1
2
3
4
5
6
7
8
# 打印第1列和第3列
$ echo "John 25 Engineer" | awk '{print $1, $3}'
John Engineer

# 处理文件
$ awk '{print $1, $4}' /var/log/nginx/access.log
203.0.113.5 [17/Jan/2026:10:00:00
198.51.100.3 [17/Jan/2026:10:01:23

指定分隔符

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# 处理/etc/passwd(冒号分隔)
$ awk -F: '{print $1, $3, $7}' /etc/passwd
root 0 /bin/bash
daemon 1 /usr/sbin/nologin
www-data 33 /usr/sbin/nologin
deploy 1000 /bin/bash

# 用Tab作为输出分隔符
$ awk -F: 'BEGIN{OFS="\t"} {print $1, $3}' /etc/passwd
root    0
daemon  1

内置变量

变量含义
$0整行
$1-$N第N列
NR行号
NF当前行的列数
FS输入分隔符
OFS输出分隔符

条件过滤

1
2
3
4
5
6
7
8
# 打印第3列大于1000的行(找普通用户)
$ awk -F: '$3 >= 1000 {print $1, $3}' /etc/passwd
deploy 1000
testuser 1001

# 打印包含error的行
$ awk '/error/ {print NR, $0}' /var/log/syslog
142 Jan 17 10:01:23 server kernel: [error] something went wrong

实战示例

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
# 统计Nginx日志中每个IP的访问次数(Top 10)
$ awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -10
   1523 203.0.113.5
    892 198.51.100.3
    456 192.0.2.100

# 统计每小时的请求量
$ awk '{print $4}' /var/log/nginx/access.log | cut -d: -f2 | sort | uniq -c
    120 08
    350 09
    890 10
    756 11
    445 12

# 计算日志文件中响应时间的平均值
$ awk '{sum+=$NF; count++} END{print "平均响应时间:", sum/count, "ms"}' response_times.log
平均响应时间: 125.6 ms

# 统计磁盘使用超过80%的分区
$ df -h | awk 'NR>1 {gsub(/%/,"",$5); if($5>80) print $6, $5"%"}'
/data 85%

组合使用

三剑客经常组合使用,威力更大:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
# 找出访问量最大的IP,并查看它请求了哪些URL
$ TOP_IP=$(awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -1 | awk '{print $2}')
$ grep "$TOP_IP" /var/log/nginx/access.log | awk '{print $7}' | sort | uniq -c | sort -rn | head -10

# 批量替换多个配置文件中的域名
$ grep -rl "old-domain.com" /etc/nginx/ | xargs sed -i 's/old-domain.com/new-domain.com/g'

# 分析SSH暴力破解(失败登录Top 10 IP)
$ grep "Failed password" /var/log/auth.log | awk '{print $(NF-3)}' | sort | uniq -c | sort -rn | head -10
    523 203.0.113.50
    234 198.51.100.99
     89 192.0.2.200

总结

场景用什么
搜索特定内容grep
替换文本内容sed
按列统计分析awk
复杂日志分析三者组合

学会这三个工具,日志分析和文本处理基本就不在话下了。

更多Linux基础命令可以参考Linux最常用的50个命令速查表。日志分析的更多技巧,推荐阅读Linux日志管理与分析

Grep Sed Awk 文本处理
cd ..