文本处理
Linux 提供了强大的文本处理工具,可以高效地搜索、过滤、转换文本内容。
grep - 文本搜索
grep 是最常用的文本搜索工具,用于在文件中查找匹配模式的行。
基本用法
# 在文件中搜索字符串
grep "pattern" file.txt
# 搜索多个文件
grep "pattern" file1.txt file2.txt
# 递归搜索目录
grep -r "pattern" /path/to/dir
# 忽略大小写
grep -i "pattern" file.txt
# 显示行号
grep -n "pattern" file.txt
# 显示不匹配的行
grep -v "pattern" file.txt
常用选项
| 选项 | 说明 |
|---|---|
-i | 忽略大小写 |
-v | 反向匹配(显示不匹配的行) |
-n | 显示行号 |
-c | 只显示匹配行数 |
-l | 只显示文件名 |
-r | 递归搜索目录 |
-w | 匹配整个单词 |
-A n | 显示匹配行及后 n 行 |
-B n | 显示匹配行及前 n 行 |
-C n | 显示匹配行及前后各 n 行 |
-E | 使用扩展正则表达式 |
正则表达式
# 使用正则表达式
grep -E "^error" file.txt # 以 error 开头
grep -E "error$" file.txt # 以 error 结尾
grep -E "[0-9]+" file.txt # 包含数字
grep -E "a.b" file.txt # a 和 b 之间有任意字符
grep -E "a*b" file.txt # a 出现 0 次或多次
grep -E "a+b" file.txt # a 出现 1 次或多次
grep -E "(abc)+" file.txt # abc 出现 1 次或多次
grep -E "a\|b" file.txt # a 或 b
# 常用正则模式
grep -E "[a-zA-Z]+" file.txt # 字母
grep -E "[0-9]{3}" file.txt # 三个数字
grep -E "[0-9]{3,5}" file.txt # 3 到 5 个数字
实际应用
# 查找包含 error 的日志
grep -i "error" /var/log/syslog
# 查找特定用户的登录记录
grep "username" /var/log/auth.log
# 统计匹配行数
grep -c "error" application.log
# 查找配置文件中的非注释行
grep -v "^#" /etc/ssh/sshd_config | grep -v "^$"
# 查找 IP 地址
grep -E "[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}" access.log
sed - 流编辑器
sed 是一个强大的流编辑器,用于文本转换和替换。
基本语法
sed [选项] '命令' 文件
替换操作
# 替换每行第一个匹配
sed 's/old/new/' file.txt
# 替换每行所有匹配
sed 's/old/new/g' file.txt
# 只替换第 n 个匹配
sed 's/old/new/2' file.txt
# 替换特定行
sed '3s/old/new/' file.txt # 第 3 行
sed '3,5s/old/new/' file.txt # 第 3-5 行
# 使用不同的分隔符
sed 's#/old#/new#' file.txt # 适合处理路径
# 忽略大小写
sed 's/old/new/gi' file.txt
删除操作
# 删除匹配行
sed '/pattern/d' file.txt
# 删除空行
sed '/^$/d' file.txt
# 删除注释行
sed '/^#/d' file.txt
# 删除指定行
sed '3d' file.txt # 删除第 3 行
sed '3,5d' file.txt # 删除第 3-5 行
sed '$d' file.txt # 删除最后一行
插入和追加
# 在匹配行前插入
sed '/pattern/i\新行内容' file.txt
# 在匹配行后追加
sed '/pattern/a\新行内容' file.txt
# 在文件开头插入
sed '1i\标题' file.txt
# 在文件末尾追加
sed '$a\结尾' file.txt
修改文件
# 直接修改文件(慎用)
sed -i 's/old/new/g' file.txt
# 创建备份后修改
sed -i.bak 's/old/new/g' file.txt
实际应用
# 移除 HTML 标签
sed 's/<[^>]*>//g' file.html
# 删除行首空格
sed 's/^[ \t]*//' file.txt
# 删除行尾空格
sed 's/[ \t]*$//' file.txt
# 替换 Windows 换行符为 Unix 格式
sed 's/\r$//' file.txt
# 在每行开头添加内容
sed 's/^/prefix /' file.txt
# 在每行末尾添加内容
sed 's/$/ suffix/' file.txt
awk - 文本处理语言
awk 是一个强大的文本处理语言,适合处理结构化数据。
基本语法
awk '模式 { 动作 }' 文件
基本用法
# 打印整行
awk '{ print }' file.txt
# 打印第一列
awk '{ print $1 }' file.txt
# 打印第一和第三列
awk '{ print $1, $3 }' file.txt
# 打印最后一列
awk '{ print $NF }' file.txt
# 打印行号
awk '{ print NR, $0 }' file.txt
# 打印列数
awk '{ print NF }' file.txt
指定分隔符
# 使用逗号作为分隔符
awk -F',' '{ print $1 }' file.csv
# 使用制表符作为分隔符
awk -F'\t' '{ print $1 }' file.tsv
# 使用多个分隔符
awk -F'[,:]' '{ print $1 }' file.txt
条件过滤
# 打印第三列大于 100 的行
awk '$3 > 100 { print }' file.txt
# 打印第一列等于特定值的行
awk '$1 == "value" { print }' file.txt
# 打印包含特定模式的行
awk '/pattern/ { print }' file.txt
# 组合条件
awk '$3 > 100 && $3 < 200 { print }' file.txt
内置变量
| 变量 | 说明 |
|---|---|
$0 | 当前整行 |
$1, $2... | 第 1, 2... 列 |
NF | 当前行的列数 |
NR | 当前行的行号 |
FS | 字段分隔符 |
RS | 行分隔符 |
OFS | 输出字段分隔符 |
ORS | 输出行分隔符 |
FILENAME | 当前文件名 |
BEGIN 和 END
# BEGIN:处理前执行
# END:处理后执行
awk 'BEGIN { print "开始处理" }
{ print $1 }
END { print "处理完成" }' file.txt
# 计算总和
awk '{ sum += $1 } END { print sum }' numbers.txt
# 计算平均值
awk '{ sum += $1 } END { print sum/NR }' numbers.txt
# 统计行数
awk 'END { print NR }' file.txt
实际应用
# 处理日志文件
awk '{ print $1 }' access.log | sort | uniq -c | sort -rn | head -10
# 提取特定字段
awk -F':' '{ print $1 }' /etc/passwd
# 计算文件大小总和
ls -l | awk '{ sum += $5 } END { print sum }'
# 格式化输出
awk '{ printf "%-10s %5d\n", $1, $2 }' file.txt
# 筛选特定范围的行
awk 'NR >= 10 && NR <= 20' file.txt
cut - 列提取
cut 命令用于提取文件中的列。
基本用法
# 提取第 2 列(按字节)
cut -b 2 file.txt
# 提取第 2-5 列(按字节)
cut -b 2-5 file.txt
# 提取指定字段
cut -f 1 file.txt
# 指定分隔符
cut -d':' -f 1 /etc/passwd
# 提取多个字段
cut -d':' -f 1,3,7 /etc/passwd
# 提取字段范围
cut -d':' -f 1-3 /etc/passwd
sort - 排序
sort 命令用于对文本行进行排序。
基本用法
# 默认排序(按字典序)
sort file.txt
# 数字排序
sort -n file.txt
# 逆序排序
sort -r file.txt
# 按指定列排序
sort -k 2 file.txt
# 按指定列数字排序
sort -k 2 -n file.txt
# 指定分隔符
sort -t':' -k 3 -n /etc/passwd
# 去重
sort -u file.txt
# 检查是否已排序
sort -c file.txt
uniq - 去重
uniq 命令用于去除重复行(必须先排序)。
基本用法
# 去除连续重复行
sort file.txt | uniq
# 显示重复次数
sort file.txt | uniq -c
# 只显示重复行
sort file.txt | uniq -d
# 只显示不重复行
sort file.txt | uniq -u
# 忽略大小写
sort file.txt | uniq -i
wc - 统计
wc 命令用于统计文件的行数、单词数和字节数。
基本用法
# 统计行数
wc -l file.txt
# 统计单词数
wc -w file.txt
# 统计字节数
wc -c file.txt
# 统计字符数(多字节字符)
wc -m file.txt
# 统计所有
wc file.txt
tr - 字符转换
tr 命令用于转换或删除字符。
基本用法
# 转换小写为大写
echo "hello" | tr 'a-z' 'A-Z'
# 转换大写为小写
echo "HELLO" | tr 'A-Z' 'a-z'
# 删除字符
echo "hello123" | tr -d '0-9'
# 删除非数字字符
echo "hello123" | tr -cd '0-9'
# 压缩重复字符
echo "hello world" | tr -s ' '
# 删除换行符
cat file.txt | tr -d '\n'
head 和 tail - 查看文件头尾
# 查看文件前 10 行
head file.txt
# 查看文件前 n 行
head -n 20 file.txt
# 查看文件后 10 行
tail file.txt
# 查看文件后 n 行
tail -n 20 file.txt
# 实时查看文件末尾(日志监控)
tail -f /var/log/syslog
# 查看文件中间部分
head -n 50 file.txt | tail -n 20
实战示例
日志分析
# 统计访问量最大的 IP
awk '{ print $1 }' access.log | sort | uniq -c | sort -rn | head -10
# 统计 HTTP 状态码
awk '{ print $9 }' access.log | sort | uniq -c | sort -rn
# 查找特定时间段的日志
awk '/2024-01-01 10:00/,/2024-01-01 11:00/' access.log
# 统计每小时的请求量
awk '{ print substr($4, 14, 2) }' access.log | sort | uniq -c
数据处理
# CSV 文件处理
awk -F',' '{ print $1, $3 }' data.csv
# 提取 JSON 中的字段(需要 jq)
cat data.json | jq '.name'
# 合并两个文件的行
paste file1.txt file2.txt
# 比较两个文件
diff file1.txt file2.txt
小结
本章我们学习了:
- grep:文本搜索和正则匹配
- sed:流编辑和文本替换
- awk:结构化数据处理
- cut:列提取
- sort:排序
- uniq:去重
- wc:统计
- tr:字符转换
- head/tail:查看文件头尾
练习
- 使用 grep 查找
/var/log目录下所有包含 "error" 的日志行 - 使用 sed 替换文件中的所有空格为下划线
- 使用 awk 计算
/etc/passwd文件中的用户数量 - 使用管道组合多个命令分析日志文件