《Shell 文本处理命令速查(grep/sed/awk/cut/tr/sort)》

《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 典型场景汇总

  1. 排错日志:grep -C 10 error error.log,把二进制日志当文本:grep -a。
  2. 统计报表:awk 切字段 → sort 排序 → uniq -c 计数 → head 取 TopN。
  3. 批量改配置:find ... -exec sed -i 's/a/b/g' {} + 结合使用。
  4. 清洗数据:tr -d '\r' 去掉 Windows 换行、cut -d, -f1 提取列。
阅读 — · 全站 —
🎸 我的歌单 0 首