1979 字
10 分钟
Shell 三剑客八股
一、三剑客总览与选型
面试官常问“三者的区别是什么”或“什么场景用谁”。记住一个口诀:grep 负责“查”,sed 负责“改”,awk 负责“算”和“格式化”。
| 工具 | 核心职责 | 一句话选型 |
|---|---|---|
| grep | 文本过滤与搜索 | 仅需查找、计数或筛选行,就用 grep。 |
| sed | 文本编辑与替换 | 需要替换、删除、插入文本行,就用 sed。 |
| awk | 文本格式化与分析 | 需要按列处理、统计计算、生成报告,就用 awk。 |
二、grep(文本搜索器)
1. 核心功能
在文件或输入流中,根据正则表达式搜索文本,并打印匹配的行。
2. 高频选项
| 选项 | 含义 |
|---|---|
-i | 忽略大小写 |
-v | 反向匹配,显示不包含模式的行 |
-n | 显示匹配行的行号 |
-c | 只输出匹配行的总数 |
-l | 只输出包含匹配内容的文件名 |
-r | 递归搜索目录下的所有文件 |
-E | 使用扩展正则表达式(支持+、?、` |
-o | 只输出匹配到的部分,而不是整行 |
-A n | 显示匹配行及其后 n 行(After) |
-B n | 显示匹配行及其前 n 行(Before) |
-C n | 显示匹配行及其前后各 n 行(Context) |
--include | 仅在指定类型的文件中搜索 |
-m n | 匹配 n 次后停止读取 |
3. 典型面试题
| 题目 | 命令示例 |
|---|---|
| 显示匹配行及其后2行 | grep -A 2 "pattern" file.txt |
在file.txt中查找包含”error”或”fail”的行并显示行号 | grep -n -E “error|fail” file.txt |
统计file.txt中”error”出现的总次数 | grep -o “error” file.txt | wc -l |
过滤掉文件中的空行和注释行(以#开头) | grep -vE ’^#|^$’ file.txt |
递归查找/etc/下所有.conf文件中包含”port”的行 | grep -r --include="*.conf" "port" /etc/ |
| 找出当前目录下包含”127.0.0.1”的文件 | grep "127.0.0.1" \find -type f“ |
| 匹配以数字开头的行 | grep "^[0-9]" file.txt |
| 匹配IPv4地址 | grep -E "([0-9]{1,3}\.){3}[0-9]{1,3}" file.txt |
4. 进阶考点:正则表达式引擎
grep默认使用NFA(非确定性有限自动机)引擎。需注意**灾难性回溯(Catastrophic Backtracking)**问题,例如模式(a+)+b匹配一长串a会消耗极长时间。生产环境中,对超大文件使用-m参数限制匹配次数是常见的优化手段。
三、sed(流编辑器)
1. 核心功能
非交互式地编辑文本流,主要进行“取行、删除、替换、插入”等操作。
2. 高频选项与命令
| 选项/命令 | 含义 |
|---|---|
-n | 安静模式,仅显示被p命令处理的行 |
-i | 直接修改原文件(非常危险,生产环境慎用) |
-E / -r | 使用扩展正则表达式 |
a | 追加,在指定行后添加新行 |
d | 删除指定行 |
p | 打印指定行 |
s/old/new/g | 替换,g可选,表示全局替换 |
/pattern/ | 模式匹配,可包含正则,/ 需要转义 \/ |
a,b | 多行,从第 a 行到第 b 行 |
/pattern1/,/pattern2/ | 按范围匹配,表示从匹配 pattern1 的行到匹配 pattern2 的行 |
/pattern1/,// | 按范围匹配,表示从匹配 pattern1 的行到下次匹配相同的行 |
3. 典型面试题
| 题目 | 命令示例 |
|---|---|
将文件中所有apple替换为orange并直接修改文件 | sed -i 's/apple/orange/g' file.txt |
| 删除文件的第5到第10行 | sed '5,10d' file.txt |
| 显示文件的第3到第10行 | sed -n '3,10p' file.txt |
| 删除文件中的所有空行 | sed '/^$/d' file.txt |
删除所有以#或//开头的注释行 | sed ’/^#|^///d’ file.txt |
| 在文件末尾追加一行”END OF FILE” | sed '$a END OF FILE' file.txt |
将/etc/passwd中所有nologin替换为bash | sed -i 's/nologin/bash/g' /etc/passwd |
4. 进阶考点:定址与分组
- 定址(Addressing):可以指定操作的行范围,如
'10,20d'删除10到20行。 - 分组(Grouping):替换时使用
(...)分组,并用\1、\2引用。例如sed -r 's#(^[^:]+):.*#\1#g'可以提取/etc/passwd中的用户名。(实际取列推荐下面的cut -d: -f1,2,...,-d 指定分隔符,-f 跟提取第几列,提取多列用逗号分隔)
| 正则 | 说明 |
|---|---|
s#...#...#g | 替换命令,用 # 作分隔符(避免和内容里的 / 冲突) |
(^[^:]+) | 第 1 个捕获组:行首开始,一个或多个非冒号字符 |
: | 匹配一个冒号 |
.* | 匹配冒号后面的所有内容 |
\1 | 替换为第 1 个捕获组的内容 |
四、awk(文本分析器)
1. 核心功能
一种强大的文本分析和格式化输出编程语言,以行为单位,默认以空白符为分隔符将行切分为字段。
2. 高频内置变量
| 变量 | 含义 |
|---|---|
$0 | 整行内容 |
$1, $2, ... | 第1、2…个字段 |
NF | 当前行的字段总数(Number of Fields) |
NR | 当前行的行号(Number of Records) |
FS | 输入字段分隔符,默认为空白符 |
OFS | 输出字段分隔符,默认为空白符 |
RS | 输入记录分隔符,默认为换行符 |
ORS | 输出记录分隔符,默认为换行符 |
FILENAME | 当前正在处理的文件名 |
3. 高频选项与模式
| 选项/模式 | 含义 |
|---|---|
-F | 指定输入字段分隔符,如-F: |
BEGIN{...} | 在处理第一行文本之前执行 |
END{...} | 在处理完所有文本之后执行 |
/pattern/ | 匹配正则表达式的行 |
! /pattern/ | 不匹配正则表达式的行 |
4. 典型面试题
| 题目 | 命令示例 |
|---|---|
取出/etc/passwd的第一列(用户名) | awk -F: '{print $1}' /etc/passwd |
打印文件file.txt的行号和整行内容 | awk '{print NR, $0}' file.txt |
打印每行的字段总数(NF) | awk '{print NF}' file.txt |
统计/etc/passwd中用户总数 | awk -F: 'END{print NR}' /etc/passwd |
| 过滤出奇数行 | awk 'NR%2==1' file.txt |
| 提取网卡IP地址(多种实现) | ip a | awk ’/([0-9]{1,3}.){3}[0-9]{1,3}/{print $2}’ |
| 统计Nginx日志中独立IP数 | awk '{dic[$1]++}END{for(i in dic) print i}' access.log |
| 求第二列和 | awk '{sum+=$2} END{print sum}' 1.log |
| 查空行 | awk '/^$/{print NR}' file1.txt |
5. 进阶考点:BEGIN与END
awk脚本可以包含BEGIN和END代码块,分别用于初始化和汇总。例如,在BEGIN中设置分隔符FS=":",在END中打印统计总数,是极其常见的用法。
五、综合对比与常见组合
1. 三剑客对比总结
| 工具 | 核心优势 | 适用场景 |
|---|---|---|
| grep | 速度最快,简单查找 | 日志过滤、内容搜索 |
| sed | 行编辑能力最强 | 批量替换、文本格式化 |
| awk | 列处理和统计能力最强 | 日志分析、数据报告 |
2. 经典组合用法
grep+awk:先用grep粗筛,再用awk精处理。grep "ERROR" app.log | awk '{print $1, $NF}'。- 统计
php.ini中每个单词出现次数:grep -oE '[a-zA-Z]+' php.ini | awk '{dic[$0]++}END{for(i in dic) print i, dic[i]}'
find+xargs+grep:在大量文件中搜索内容。例如:find . -name "*.log" | xargs grep "timeout"。grep+sed:查找并替换。例如:grep -l "old" *.txt | xargs sed -i 's/old/new/g'。
六、其他文本处理命令
1. 命令
cut:按列切分,cut -d: -f1 /etc/passwd。sort:排序,-n(数字)、-r(逆序)、-k(指定列)、-t(指定分隔符)、-u(去重,等价于sort 'filename' | uniq)。uniq:去重(必须配合sort使用,仅去除相邻重复行)。常用sort | uniq -c统计次数。tr:字符替换/删除,tr 'A-Z' 'a-z'(大小写转换)、tr -d '\r'(删除回车)。xargs:将标准输入转为命令行参数。find . -name "*.log" | xargs rm -f(解决参数过长问题)。
2. 经典组合用法
- 查找当前目录所有包含有字符”123”的文件名称:
grep -r "123" /root | cut -d: -f1 | sort -u
七、正则表达式规则
基础正则表达式(BRE)
- ^ / $:匹配行首、行尾
- .:匹配除换行符外的任意单字符
- *:匹配前一字符 0 次或多次
- [list] / [^list]:匹配列表内或不在列表内的任意字符
- {n}, {n,}, {n,m}:匹配前一字符的固定或范围次数(需转义
\{ \})
扩展正则表达式(ERE)
- +:匹配前一字符 1 次或多次
- ?:匹配前一字符 0 次或 1 次
- ():分组,将括号内模式视为整体
- |:逻辑或,匹配任一模式
- {n}, {n,}, {n,m}:次数匹配(无需转义)
分享文章
生成精美分享图或复制链接,与更多人分享本文。
继续阅读
换条路线
从其他文章中稳定抽取
最后更新于 ,距今已过 35 天
部分内容可能已过时