《Shell 文本处理命令速查(grep/sed/awk/cut/tr/sort)》
Shell 文本处理是日常运维与日志分析的基础技能,本文汇总 grep/sed/awk/cut/tr/sort/echo/yes 等命令的常见用法与典型场景。数据以管道线式处理:命令A | 命令B。
1 grep:文本检索
grep 用于在文件或标准输入中检索匹配的行,支持基础正则(BRE)与扩展正则(ERE,需 -E 或 egrep)。
常见用法:
# 显示匹配行和其后 5 行(After)
grep keyword app.log -A 5
# 显示匹配行和其前 5 行(Before)
grep keyword app.log -B 5
# 显示匹配行和其前后各 5 行(Context)
grep keyword app.log -C 5
排除目录和后缀:
# 排除指定目录
grep --exclude-dir=log --exclude-dir=lib 192.168.1.14 -inr .
# 排除以 .log 结尾的文件
grep -E "192.168.1.29" -nr --exclude=*.log .
处理二进制文件的几个开关:
-a:把二进制文件当文本处理,解决报错Binary file (standard input) matches。-I:忽略二进制文件(相当于--binary-files=without-match)。-Hn:输出时带上文件名(-H)与行号(-n)。
查找 IPv4 地址:
grep "[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}" test.txt
过滤掉包含多个空格的行(匹配到 字段 + 至少两个空格 的行被丢掉):
grep -Ev "http_signature_fingerprints\s+\[" src.txt > result.txt
2 sed:流式文本编辑器
sed(stream editor)逐行读取并处理文本,常用于删除、替换、插入。-i 表示原地修改(带上 -r 表示启用扩展正则)。
注意:sed 中的
&是元字符,代表整个被匹配的字符串,替换时若想输出字面的&需要用\&转义。
删除与清理:
# 删除以 # 开头的行(注释行)
sed -ri '/^#/d' file
# 删除空行
sed -ri '/^$/d' file
# 删除所有空格
sed -i 's/[[:space:]]//g' udp.txt
# 删除包含特定字符串的行
sed -e '/abc/d' a.txt > b.txt
# 删除每行行首的空白
sed -i 's/^\s//g' file.txt
在匹配位置插入内容:
# 在匹配之后插入 content
sed -i 's/pattern/&content/' hello.txt
# 在匹配之前插入 content
sed -i 's/pattern/content&/' hello.txt
# 在匹配行行首插入 content
sed -i 's/.*pattern.*/content&/' hello.txt
# 在匹配行的行首插入 #(注释掉)
sed -i '/^data/a\ ' cc-log.txt
# 在指定行(1、2 行)行尾追加 |
sed -i '1,2s/$/&|/' ip_zones.txt
替换:
# 全局替换,替换指定目录下所有文件(Grep 搜索结果)
sed -i "s/old/new/g" $(grep old -rl directory_path)
# 取出行内某个数字并重写整行
# 文件内容:cluster-config-file cluster-6303-node.conf
sed -i "s#.*-\([0-9]\+\)-.*#cluster-config-file \1.conf#g" file
去除 Windows 换行符(\r):
cat input_file | sed 's/\r$//' > result_file
删除代码中的注释(单行与多行):
sed -i '/\/\*.*\*\// d; /\/\*/,/\*\// d' x.js
sed -i '/\/\/.*/ d' x.js
3 awk:按列处理
awk 是最强大的文本数据处理工具之一,按分隔符切分成字段($1、$2…),擅长取列与统计。-F 指定输入字段分隔符。
基础用法:
- 取版本号:将 stderr 重定向到
tee后再用 awk 取字段
/usr/local/nginx/sbin/nginx -v 2>&1 | tee | awk -F " " '{print substr($4, 2, length($4) - 2)}' | awk -F "-" '{print $1}'
- 统计访问日志中 Top10 客户端 IP(
$1为 access.log 第一列,即 client ip)
awk '{print $1}' access.log | sort | uniq -c | sort -n -r | head
- split 函数按逗号切分字段并重拼接
awk '{
split($1, parts, ",");
zone = parts[1];
zone_id = parts[2];
print zone "," zone_id
}' head.txt
- 结合 shell 变量:可以用
-v var=$shell_var传入。
4 cut/tr:拆字段与字符集转换
cut 按分隔符取出指定字段,tr 做字符集合的翻译、删除。
# 按 , 分隔取第 1 个字段
echo "hello,world" | cut -d "," -f1 # hello
# 全部大写转小写
tr A-Z a-z < input
tr '[:upper:]' '[:lower:]' < input
# 只保留指定字符集(小写字母、数字、-)
echo "Ahello-world520Z" | tr -dc a-z0-9- # hello-world520
# 删除文件中的换行符
tr -d '\n' < src.txt > dst.txt
# 删除末尾的 \r(去除 Windows 换行)
cat filename1 | tr -d "\r" > newfile
5 sort:按字段排序
sort 用于行排序,配合 uniq 统计去重。
# 以 : 为分隔符,按第 2 字段数值排序
sort -n -k 2 -t : facebook.txt
# 常见日志统计:IP 计数降序
awk '{print $1}' access.log | sort | uniq -c | sort -rn
常用参数:-n 按数值排序、-r 降序、-t 指定分隔符、-k 指定排序字段、-u 去重。
6 echo/yes:输出工具
# -e 使转义符生效(\n 换行),-n 不输出结尾换行符
echo -e "hello\nworld"
echo -n "hello"
yes 用于自动填充交互式确认,例如批量安装、批量确认:
yes "yes" | command-that-asks-for-input
其他小工具:
- 去掉文件末尾换行符:
cat file | xargs echo -n | xargs echo - 生成指定位数随机字符串(保留指定字符集):
# 输出长度为 8 的随机字符串(仅 a-z0-9- 字符集)
< /dev/urandom tr -dc a-z0-9- | head -c8; echo
7 典型场景汇总
- 排错日志:
grep -C 10 error error.log,把二进制日志当文本:grep -a。 - 统计报表:
awk切字段 →sort排序 →uniq -c计数 →head取 TopN。 - 批量改配置:
find ... -exec sed -i 's/a/b/g' {} +结合使用。 - 清洗数据:
tr -d '\r'去掉 Windows 换行、cut -d, -f1提取列。
阅读 —
·
全站 —