Bash 常用命令与管道操作:grep/sed/awk/cut/sort
一、引言
在 Linux 日常运维和脚本编写中,文本处理是最高频的操作之一。Bash 提供了丰富的命令行工具,配合管道(|)可以将多个命令串联起来,完成复杂的数据处理任务。
二、grep 命令
grep 是最常用的文本搜索工具,支持正则表达式匹配。
#!/bin/bash
grep 基本用法示例
基本搜索
grep "error" /var/log/syslog
忽略大小写
grep -i "warning" system.log
反向匹配
grep -v "debug" app.log
显示行号
grep -n "failed" auth.log
递归搜索
grep -r "TODO" ./src/
只显示文件名
grep -l "function" *.php
统计匹配行数
grep -c "error" app.log
显示上下文
grep -B 2 -A 3 "exception" error.log
正则表达式
grep -E "^[0-9]{3}-[0-9]{4}$" phone.txt
搜索多个关键词
grep -E "error|fail|warning" system.log
三、sed 命令
sed 是流编辑器,主要用于文本替换、删除和插入操作。
#!/bin/bash
sed 基本用法示例
基本替换
sed "s/old/new/" file.txt
全局替换
sed "s/old/new/g" file.txt
指定行号替换
sed "3s/old/new/" file.txt
原地编辑(先备份)
sed -i.bak "s/old/new/g" file.txt
删除指定行
sed "3d" file.txt
sed "/pattern/d" file.txt
多个操作
sed -e "s/foo/bar/g" -e "s/baz/qux/g" file.txt
打印指定行
sed -n "5,10p" file.txt
四、awk 命令
awk 是强大的文本分析工具,支持按字段处理。
#!/bin/bash
awk 基本用法示例
打印所有行
awk "{print}" data.txt
打印指定列
awk "{print \$1, \$3}" data.txt
指定分隔符
awk -F: "{print \$1, \$7}" /etc/passwd
条件过滤
awk "\$3 > 100 {print \$1, \$3}" data.txt
内置变量
awk "{print "行号:" NR, "字段数:" NF}" data.txt
计算总和
awk "BEGIN{sum=0} {sum+=\$3} END{print "总和:" sum}" data.txt
计算平均值
awk "{sum+=\$2; count++} END{printf "平均值: %.2f\n", sum/count}" data.txt
五、cut 与 sort 命令
#!/bin/bash
cut 基本用法
cut -c 1-10 file.txt
cut -d: -f1,3,5 /etc/passwd
sort 基本用法
sort names.txt
sort -n numbers.txt
sort -r data.txt
sort -t, -k3,3n data.csv
sort data.txt | uniq
sort data.txt | uniq -c | sort -rn
六、管道组合实战
#!/bin/bash
管道组合实战
统计日志错误次数并排序
grep "ERROR" app.log | cut -d" " -f1 | sort | uniq -c | sort -rn
查找最常用命令
history | awk "{print \$2}" | sort | uniq -c | sort -rn | head -10
统计 IP 访问量
awk "{print \$1}" access.log | sort | uniq -c | sort -rn | head -20
提取进程信息
ps aux | awk "NR>1 {print \$6, \$11}" | sort -rn | head -10
批量重命名
ls *.txt | sed "s/\(.*\)\.txt/mv & \1.md/" | bash
七、常见问题(FAQ)
Q1: grep 搜索的字符串包含特殊字符怎么办?
使用 -F 选项将模式解释为固定字符串,或用 fgrep。
Q2: sed 的 -i 选项会直接修改文件吗?
是的,sed -i 会直接原地编辑文件。建议先用 sed -i.bak 备份。
Q3: awk 中 $0、$1、$NF 有什么区别?
$0 表示整行内容,$1 表示第一列,$NF 表示最后一列。
Q4: 如何让管道处理中文?
设置 export LANG=zh_CN.UTF-8。如果仍有乱码,用 iconv 转换编码。
八、延伸阅读
- Linux 文本处理三剑客:深入了解 grep/sed/awk 的高级用法
- Linux Shell 脚本编程入门:变量、条件判断与循环基础
- Linux 环境变量与脚本调试:学习 export、set -x 等调试技巧