grep / awk / sed 文本处理速查表
TL;DR
grep 默认使用基本正则(BRE,即 -G),-E 切换为扩展正则,-F 按固定字符串匹配,-P 使用 PCRE 且与 -z 组合时属实验性。grep -m NUM 在输出 NUM 行匹配后停止,NUM 为 0 时立即停止,-1 视为无限(默认)。sed 默认自动打印模式空间,-n 抑制该行为;-i[SUFFIX] 原地编辑并在给出 SUFFIX 时备份。-n 与 p 组合是 sed 只输出指定行的标准写法。
核心选项与默认值对照
| 项目/要点 | 值或说明 | 注意事项 |
|---|---|---|
| grep 默认正则方言 | -G 基本正则(BRE) | 未指定 -E、-F、-P 时生效 |
| grep 扩展正则 | -E 或 --extended-regexp | 解释为 ERE |
| grep 固定字符串 | -F 或 --fixed-strings | 不按正则解释 PATTERNS |
| grep Perl 正则 | -P 或 --perl-regexp | 与 -z 组合时属实验性,可能警告未实现特性 |
| grep 忽略大小写 | -i 或 --ignore-case | 默认不忽略,可用 --no-ignore-case 抵消脚本中的 -i |
| grep 反向匹配 | -v 或 --invert-match | 与 -c 同用时统计非匹配行数 |
| grep 整词匹配 | -w 或 --word-regexp | 与 -x 同用时 -w 无效 |
| grep 整行匹配 | -x 或 --line-regexp | 等价于给模式加 ^ 与 $ |
| grep 最大匹配行数 | -m NUM,默认 -1 即无限 | NUM 为 0 时立即停止且不读输入 |
| grep 仅输出匹配部分 | -o 或 --only-matching | 每个匹配部分单独一行 |
| grep 行号与前缀 | -n 行号(1 起)、-b 字节偏移(0 起)、-H 文件名、-h 抑制文件名 | 多文件搜索时 -H 为默认,单文件或标准输入时 -h 为默认 |
| grep 文件名列表 | -l 有匹配的文件名、-L 无匹配的文件名 | -l 在首次匹配后停止扫描该文件 |
| grep 静默与错误抑制 | -q 不写标准输出、-s 抑制不存在或不可读文件的错误 | -q 找到任一匹配即以零状态立即退出 |
| grep 空字节分隔 | -Z 或 --null | 文件名后输出 ASCII NUL 而非换行 |
| sed 抑制自动打印 | -n、--quiet、--silent | 常与 p 组合只打印指定行 |
| sed 原地编辑 | -i[SUFFIX] 或 --in-place[=SUFFIX] | 给出 SUFFIX 时生成备份 |
| sed 扩展正则 | -E、-r、--regexp-extended | 可移植写法用 POSIX -E |
| sed 脚本来源 | -e script、-f script-file | 两者都未给出时,第一个非选项参数作为脚本 |
| sed 文件独立处理 | -s 或 --separate | 行号按文件分别累计而非跨文件连续 |
| sed 空字节分隔 | -z 或 --null-data | 以 NUL 字符分隔行 |
| sed 替换命令 | s/regexp/replacement/ | replacement 中 & 指代整个匹配,\1 到 \9 指代子表达式 |
| sed 地址范围 | addr1,addr2 | addr1 匹配行总被接受;addr2 为正则时不测试 addr1 匹配的那一行 |
| sed 地址取反 | 地址后加 ! | 命令仅在地址不匹配时执行 |
常用操作与命令
grep:按模式类型与输出形态选择选项
先确定模式类型:普通文本用 -F 避免正则元字符干扰,需要 +、?、{} 等写法用 -E,需要 PCRE 特性用 -P。再确定输出形态:只要计数用 -c,只要匹配片段用 -o,只要文件名用 -l 或 -L,脚本判断用 -q。-m NUM 控制提前停止,-n、-b、-H 控制行前缀。
# 递归搜索当前目录,忽略大小写,输出文件名与行号
grep -rni --include='*.conf' 'timeout' .
# 固定字符串匹配,只输出匹配片段,最多 5 行
grep -F -o -m 5 'ERROR_CODE' app.log
# 列出包含匹配的文件名,以 NUL 分隔,便于 xargs -0 处理
grep -lZ 'TODO' src/*.csed:替换、删除与按地址范围处理
sed 对输入只做一遍扫描。默认自动打印模式空间,-n 关闭后需显式 p。替换用 s///,删除用 d,整行替换用 c\,字符转换用 y///。地址可以是行号、first~step 步进或正则;两个地址用逗号构成范围,! 取反。
# 原地编辑并保留 .bak 备份,把行首的 foo 替换为 bar
sed -i.bak 's/^foo/bar/' config.txt
# 只打印第 10 到 20 行
sed -n '10,20p' input.txt
# 删除空行,并删除匹配 deprecated 的行
sed -e '/^$/d' -e '/deprecated/d' notes.md组合使用:grep 过滤后交给 sed 或 awk
grep 的 -o 输出每行一个匹配片段,适合作为下游的输入。sed 的 -s 让多个文件的行号分别累计,-z 处理 NUL 分隔数据。管道中若上游是 gzip 解压流,可用 --label 让 grep 以指定文件名显示标准输入来源。
# 从日志中提取匹配片段,再统一替换分隔符
grep -o 'user=[^ ]*' access.log | sed 's/^user=//'
# 解压流搜索时用 --label 标注来源文件名
gzip -cd foo.gz | grep --label=foo -H 'some pattern'常见问题
grep 的 -E、-F、-P 有什么区别?
-E 把 PATTERNS 解释为扩展正则(ERE),-F 按固定字符串解释、不当作正则,-P 解释为 Perl 兼容正则(PCRE)。未指定任何一项时默认是 -G 基本正则(BRE)。-P 与 -z 组合时属实验性,可能警告未实现特性。
grep -m 0 和 -m -1 分别是什么行为?
-m 0 让 grep 立即停止、不读取输入;-m -1 被视为无限,grep 不会因匹配行数停止,这也是默认值。与 -c 同用时输出计数不超过 NUM;与 -v 同用时在输出 NUM 行非匹配行后停止。
sed 的 -i 会不会破坏原文件?
-i[SUFFIX] 是原地编辑,给出 SUFFIX 时会生成备份,例如 -i.bak 保留原文件副本。未给出 SUFFIX 时不生成备份,原内容被直接替换。
sed 地址范围中 addr2 是正则时有什么特殊规则?
addr1 匹配的那一行总会被接受,即使 addr2 指向更早的行;并且当 addr2 是正则时,不会对 addr1 匹配的那一行做测试。地址后加 ! 表示命令仅在地址不匹配时执行。
grep -w 和 -x 能一起用吗?
不能指望两者叠加生效:-w 在同时指定 -x 时无效。-w 要求匹配子串位于行首或前面是非单词构成字符、且位于行尾或后面是非单词构成字符;-x 要求整个匹配恰好等于整行。
来源
- https://man7.org/linux/man-pages/man1/grep.1.html(访问日期:2026-11-06)
- https://man7.org/linux/man-pages/man1/sed.1.html(访问日期:2026-11-06)