Shell 脚本中常用的文本处理工具包括 grep、sed、awk 和 cut 等。
grep - 文本搜索工具
基本用法
bash# 在文件中搜索文本 grep "pattern" file.txt # 搜索多个文件 grep "pattern" file1.txt file2.txt # 递归搜索目录 grep -r "pattern" /path/to/directory # 忽略大小写 grep -i "pattern" file.txt # 显示行号 grep -n "pattern" file.txt # 反向匹配(不包含) grep -v "pattern" file.txt # 只显示匹配的文件名 grep -l "pattern" *.txt # 统计匹配行数 grep -c "pattern" file.txt
正则表达式
bash# 匹配行首 grep "^start" file.txt # 匹配行尾 grep "end$" file.txt # 匹配数字 grep "[0-9]" file.txt # 匹配特定次数 grep "a\{3\}" file.txt # 匹配 3 个 a # 使用扩展正则表达式 grep -E "pattern1|pattern2" file.txt
实际应用
bash# 查找进程 ps aux | grep "nginx" # 查找日志中的错误 grep "ERROR" /var/log/syslog # 查找包含特定内容的文件 grep -r "TODO" ./src # 统计代码行数 grep -c "^" *.py
sed - 流编辑器
基本用法
bash# 替换文本 sed 's/old/new/' file.txt # 全局替换 sed 's/old/new/g' file.txt # 删除行 sed '3d' file.txt # 删除第 3 行 sed '/pattern/d' file.txt # 删除匹配的行 # 打印特定行 sed -n '5p' file.txt # 打印第 5 行 sed -n '1,5p' file.txt # 打印 1-5 行 # 插入和追加 sed '2i\new line' file.txt # 在第 2 行前插入 sed '2a\new line' file.txt # 在第 2 行后追加
高级用法
bash# 使用正则表达式 sed 's/[0-9]\+//g' file.txt # 多个替换 sed -e 's/old1/new1/g' -e 's/old2/new2/g' file.txt # 就地编辑(修改原文件) sed -i 's/old/new/g' file.txt # 备份后编辑 sed -i.bak 's/old/new/g' file.txt # 使用变量 var="pattern" sed "s/$var/replacement/g" file.txt
实际应用
bash# 替换配置文件中的值 sed -i 's/port=8080/port=9090/' config.ini # 删除注释行 sed '/^#/d' file.txt # 删除空行 sed '/^$/d' file.txt # 格式化输出 sed 's/\s\+/ /g' file.txt
awk - 文本处理工具
基本用法
bash# 打印特定列 awk '{print $1}' file.txt # 打印多列 awk '{print $1, $3}' file.txt # 指定分隔符 awk -F: '{print $1}' /etc/passwd # 打印行号 awk '{print NR, $0}' file.txt # 条件打印 awk '$3 > 100 {print $0}' file.txt
内置变量
bashNR # 当前记录号(行号) NF # 当前记录的字段数 $0 # 完整的记录 $1, $2 # 第 1、2 个字段 FS # 字段分隔符(默认空格) OFS # 输出字段分隔符 RS # 记录分隔符(默认换行) ORS # 输出记录分隔符
模式和动作
bash# 模式匹配 awk '/pattern/ {print $0}' file.txt # BEGIN 和 END 块 awk 'BEGIN {print "Start"} {print $0} END {print "End"}' file.txt # 计算总和 awk '{sum += $1} END {print sum}' file.txt # 计算平均值 awk '{sum += $1; count++} END {print sum/count}' file.txt
实际应用
bash# 统计文件大小 ls -l | awk '{sum += $5} END {print sum}' # 查找最大值 awk '{if ($1 > max) max = $1} END {print max}' file.txt # 格式化输出 awk '{printf "%-10s %10s\n", $1, $2}' file.txt # 处理 CSV 文件 awk -F, '{print $1, $3}' data.csv
cut - 文本切割工具
基本用法
bash# 按字符切割 cut -c 1-5 file.txt # 提取 1-5 字符 cut -c 1,5,10 file.txt # 提取第 1、5、10 字符 # 按字节切割 cut -b 1-10 file.txt # 按字段切割 cut -d: -f1 /etc/passwd # 提取第 1 个字段 cut -d: -f1,3 /etc/passwd # 提取第 1、3 个字段
实际应用
bash# 提取用户名 cut -d: -f1 /etc/passwd # 提取 IP 地址 ifconfig | grep "inet " | cut -d: -f2 | cut -d' ' -f1 # 提取文件扩展名 echo "file.txt" | cut -d. -f2
组合使用示例
日志分析
bash# 统计错误数量 grep "ERROR" /var/log/app.log | wc -l # 查找特定时间段的日志 sed -n '/2024-01-01 10:00/,/2024-01-01 11:00/p' /var/log/app.log # 提取 IP 地址 grep "ERROR" /var/log/app.log | awk '{print $5}' | cut -d: -f2 # 统计各错误类型的数量 grep "ERROR" /var/log/app.log | awk '{print $6}' | sort | uniq -c
文本处理
bash# 删除空行和注释 sed '/^$/d; /^#/d' file.txt # 替换多个空格为单个空格 sed 's/\s\+/ /g' file.txt # 提取特定列并去重 awk '{print $1}' file.txt | sort -u # 计算平均值 awk '{sum += $1} END {print sum/NR}' file.txt
系统管理
bash# 查找占用 CPU 最高的进程 ps aux | sort -rk 3 | head -n 5 # 查找占用内存最多的进程 ps aux | sort -rk 4 | head -n 5 # 统计各用户进程数 ps aux | awk '{print $1}' | sort | uniq -c # 查找特定端口的进程 lsof -i :8080 | awk '{print $2}' | tail -n +2
最佳实践
- 使用管道组合工具:
grep | awk | sort | uniq - 优先使用 grep 进行搜索: 简单搜索时最快
- 使用 sed 进行替换: 文本替换的首选工具
- 使用 awk 处理列数据: 处理结构化文本的最佳选择
- 使用 cut 提取固定位置: 简单的文本切割任务
- 注意正则表达式语法: grep 和 sed 的正则表达式略有不同
- 测试命令: 在处理重要文件前先测试命令