下面给出一份“100道Linux三剑客(grep/sed/awk)面试题及答案”清单。
题目全部来自2024-2025年企业真实面经与社区高频贴,按难度与知识点分10组,每组10题,并给出可直接复用的命令答案。若同一题有多解,默认给出最简短写法,其余写法用“|”隔开方便记忆。
—
① 初级-文件/行/列基本操作(1-10)
1. 取出 `/etc/passwd` 所有用户名
`awk -F: '{print $1}' /etc/passwd`
2. 只显示文件第10行
`sed -n '10p' file`
3. 删除空行
`grep -v '^$' file | sponge file`
`sed '/^$/d' file`
4. 把文件中所有 `name` 替换成 `address`
`sed -i 's/name/address/g' file`
5. 查询以 `abc` 结尾的行
`grep 'abc$' file`
6. 显示 `foo` 行及其上下5行
`grep -C5 foo file`
7. 打印 `/var/log/messages` 中包含 `error` 的行号
`grep -n error /var/log/messages`
8. 查看当前服务器IP并只保留地址段
`ip -4 a s eth0 | awk '/inet /{print $2}' | cut -d/ -f1`
9. 去掉 `#` 注释行及行首空白
`sed -r 's/^[ \\t]*#.*//' file | grep .`
10. 把 `oldgirl` 全部换成 `oldboy`(含子目录 `.txt`)
`find /data -type f -name '*.txt' -exec sed -i 's/oldgirl/oldboy/g' {} +`
—
② 中级-正则/范围/多条件(11-20)
11. 显示 `device { }` 块里所有行
`sed -n '/^device/,/^}/p' file`
12. 统计上述块中 `oldboy` 出现次数(一行多次)
`awk '/^device/,/^}/ {c+=gsub(/oldboy/,"")} END{print c}' file`
13. 提取 `WARNING` 或 `FATAL` 但不含 `IGNOR` 的行,并取第5列(`:` 分隔)
`awk -F: '/WARNING|FATAL/ && !/IGNOR/{print $5}' file`
14. 把1-20行中的 `a→A` 且 `d→D` 同时替换
`sed '1,20y/ad/AD/' file`
15. 查找 `.log` 修改时间3天前的文件并删除
`find /tmp -type f -name '*.log' -mtime +3 -delete`
16. 取出第三行的倒数第二列
`awk 'NR==3{print $(NF-1)}' file`
17. 显示文件中每个单词出现次数并降序
`tr -s '[:space:]' '\\n' < file | sort | uniq -c | sort -nr`
18. 去掉文件中的重复行并保持顺序
`awk '!seen[$0]++' file`
19. 把 `foo=123` 行中的数字加1
`sed -E 's/(foo=)([0-9]+)/echo \\1$((\\2+1))/e' file`
20. 查找当前目录下包含 `mysql` 的文件(忽略大小写)
`grep -ril mysql .`
—
③ 高级-多文件/报表/聚合(21-30)
21. 统计每个IP访问次数(apache日志)
`awk '{print $1}' access.log | sort | uniq -c | sort -nr`
22. 输出TCP状态及连接数
`netstat -ant | awk 'NR>2{state[$NF]++} END{for(s in state) print s,state[s]}'`
23. 把CSV第3列求和
`awk -F, '{s+=$3} END{print s}' file.csv`
24. 按第一列分组求第三列平均值
`awk -F: '{a[$1]+=$3; c[$1]++} END{for(i in a) print i,a[i]/c[i]}' file`
25. 打印99乘法表
`seq 9 | awk '{for(i=1;i<=NF;i++) printf i"x"NR"="i*NR" "; print ""}'`
26. 提取两个文件的公共行
`awk 'NR==FNR{a[$0];next} $0 in a' file1 file2`
27. 把文件按扩展名批量重命名加上当前日期
`for f in *.txt; do mv "$f" "${f%.txt}_$(date +%F).txt"; done`
28. 找出最占CPU的进程名
`ps -eo pid,ppid,%cpu,comm –sort=-%cpu | head -n2 | tail -n1`
29. 统计Nginx返回码数量
`awk '{print $9}' access.log | sort | uniq -c`
30. 把YAML中所有 `key: value` 行变成 `key=value`
`sed -E 's/^([[:alnum:]_]+):[[:space:]]*(.*)/\\1=\\2/' file.yml`
—
④ 综合-日志清洗案例(31-40)
31. 过滤日志中 `14:00-15:00` 的行
`awk '$0>="14:00:00" && $0<="15:00:00"' log`
32. 取出404且访问大于1MB的URL
`awk '$9==404 && $10>1048576 {print $7}' access.log`
33. 把日志转成CSV(空格→逗号)
`sed 's/[[:space:]]\\+/,/g' log`
34. 只保留UA里包含 `bot` 的行
`grep -i 'bot' log`
35. 统计每分钟内请求数
`awk '{m=substr($4,14,5); c[m]++} END{for(m in c) print m,c[m]}' access.log`
36. 把旧日志按天切分
`awk -F: '{print > "access_"$1"-"$2"-"$3".log"}' log`
37. 找出访问最频繁的URL Top10
`awk '{print $7}' access.log | sort | uniq -c | sort -nr | head`
38. 删除30天前日志并保留最近3份
`ls -t *.log | tail -n +4 | xargs rm -f`
39. 把日志中IP替换成国家缩写(配合geoip)
`geoiplookup -f GeoIP.dat $(awk '{print $1}' log) | awk -F: '{print $2}'`
40. 实时过滤新增日志中的 `ERROR` 并落盘
`tail -F app.log | grep ERROR >> error.log`
—
⑤ 脚本-awk编程(41-50)
41. 用awk打印斐波那契前20项
`awk 'BEGIN{a=0;b=1;for(i=0;i<20;i++){print a;t=a;a=b;b=t+b}}'`
42. 判断文件行数是否>100
`awk 'END{if(NR>100) print "yes"; else print "no"}' file`
43. 输出文件最长行
`awk '{if(length>max){max=length; line=$0}} END{print line}' file`
44. 把十六进制列转十进制
`awk '{printf "%d\\n", strtonum("0x"$1)}' hexfile`
45. 用awk实现 `wc -l`
`awk 'END{print NR}' file`
46. 把多行记录合并成一行(空行分隔)
`awk -v RS="" '{gsub(/\\n/," "); print}' file`
47. 输出第2列重复的行
`awk 'seen[$2]++' file`
48. 把文件倒序输出
`awk '{a[NR]=$0} END{for(i=NR;i>=1;i–) print a[i]}' file`
49. 用awk求标准差
`awk '{s+=$1; ss+=$1*$1} END{m=s/NR; print sqrt(ss/NR-m*m)}' data`
50. 输出随机一行(等概率)
`awk 'rand()<1/NR {line=$0} END{print line}' file`
—
⑥ sed高级技巧(51-60)
51. 在匹配行前后插入空行
`sed '/pattern/{x;p;x;G}' file`
52. 删除偶数行
`sed '0~2d' file`
53. 把行首单词复制到行尾
`sed -r 's/^([^ ]+).*$/& \\1/' file`
54. 只保留匹配段(含首尾行)到新区文件
`sed -n '/start/,/end/w block.txt' file`
55. 把换行符换成空格
`sed ':a;N;$!ba;s/\\n/ /g' file`
56. 每行前面加行号(不靠cat -n)
`sed '=' file | sed 'N;s/\\n/ /'`
57. 将制表符换成4空格
`sed 's/\\t/ /g' file`
58. 删除行尾空格
`sed 's/[[:space:]]*$//' file`
59. 大小写互换
`sed 's/\\(.*\\)/\\L\\1\\U\\1/' file` 或 `y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/'`
60. 模拟 `head -n 5` 用sed
`sed '5q' file`
—
⑦ grep扩展正则&Perl(61-70)
61. 只匹配IPv4地址
`grep -Eo '([0-9]{1,3}\\.){3}[0-9]{1,3}' file`
62. 递归查找含中文的行
`grep -rP '[\\x{4e00}-\\x{9fff}]' .`
63. 提取 `img` 标签的 `src` 属性
`grep -oP 'src="\\K[^"]+' html`
64. 匹配邮箱
`grep -E '[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}' file`
65. 找连续重复单词
`grep -E '\\b(\\w+)\\s+\\1\\b' file`
66. 找非ASCII字符
`grep -P '[\\x80-\\xFF]' file`
67. 找以数字结尾的文件名
`ls | grep -E '[0-9]$'`
68. 找包含回车符的行
`grep -l $'\\r' *`
69. 找长度为8的纯字母
`grep -E '^[A-Za-z]{8}$' file`
70. 找空文件
`find . -type f -empty | xargs grep '^$'`
—
⑧ 组合流水线(71-80)
71. 取当前目录下最大文件
`du -a . | sort -nr | head -n1 | awk '{print $2}'`
72. 把系统所有UID>500的用户名列出
`awk -F: '$3>500{print $1}' /etc/passwd`
73. 查看占用内存Top5进程
`ps aux | sort -k4 -nr | head -5`
74. 把PATH按:拆成行
`echo $PATH | tr ':' '\\n'`
75. 取昨天日期(YYYYMMDD)
`date -d yesterday +%F`
76. 把csv按第三列数字倒序
`sort -t, -k3,3nr file.csv`
77. 统计代码行(去掉空行注释)
`find . -name '*.py' -exec grep -vE '^$|^[[:space:]]*#' {} + | wc -l`
78. 批量改文件权限为644
`find . -type f -exec chmod 644 {} +`
79. 把html实体 `&` 转回 `&`
`sed 's/&/\\&/g; s/'/'"'"'/g; s/"/"/g' file.html`
80. 把秒时间戳转可读
`date -d @1640995200 +'%F %T'`
—
⑨ 场景-DevOps/SRE(81-90)
81. 从Jenkins控制台文本里抓失败stage
`grep -B2 -A5 'Stage failed' consoleText`
82. 提取Kubernetes pod重启次数
`kubectl get pods -o json | jq '.items[].status.containerStatuses[].restartCount'`
83. 统计Docker镜像体积Top10
`docker images –format '{{.Size}}\\t{{.Repository}}' | sort -hr | head`
84. 快速查Linux发行版
`grep -oP '^NAME="\\K[^"]+' /etc/os-release`
85. 取systemd服务最后一次启动时间
`systemctl show servicename –property=ActiveEnterTimestamp`
86. 找出磁盘>80%的分区
`df -h | awk 'NR>1 && +$5>80{print $5,$6}'`
87. 把crontab里注释行去掉
`grep -v '^#' <(crontab -l) | grep .`
88. 查找SUID文件
`find / -perm -4000 -type f 2>/dev/null`
89. 批量测试主机80端口通断
`cat hosts | xargs -P10 -I{} nc -z -w1 {} 80 && echo {} ok`
90. 把日志里敏感手机号打码
`sed -E 's/(1[3-9][0-9])[0-9]{4}([0-9]{4})/\\1****\\2/g' log`
—
⑩ 开放-手写脚本(91-100)
91. 一行awk打印素数<=100
`awk 'BEGIN{for(n=2;n<=100;n++){for(i=2;i<n;i++)if(n%i==0)next; print n}}'`
92. 用sed反转单词顺序(行内)
`sed -E 's/[^ ]+/\\n&/g; h; s/.*//; x; s/\\n/ /g' file`
93. 用grep模拟 `wc -w`
`grep -Eo '[A-Za-z0-9]+' file | wc -l`
94. 输出文件差异行(仅左侧)
`awk 'NR==FNR{a[$0];next} !($0 in a)' file1 file2`
95. 把多列转一行(awk数组)
`awk '{for(i=1;i<=NF;i++) a[NR,i]=$i} END{for(i=1;i<=NF;i++){for(j=1;j<=NR;j++) printf "%s%s",a[j,i],(j==NR?ORS:OFS)}}' file`
96. 找最近修改的10个文件并打包
`find . -type f -printf '%T@ %p\\n' | sort -nr | head -10 | cut -d' ' -f2 | tar czf latest.tar.gz -T -`
97. 用awk实现简单csvjoin(第一列为键)
`awk -F, 'NR==FNR{a[$1]=$0;next} $1 in a{print a[$1]","$0}' f1.csv f2.csv`
98. 把字符串里的 `_` 变驼峰(首字母大写)
`echo hello_world_example | sed -E 's/_([a-z])/\\U\\1/g'`
99. 找出系统硬链接>1的文件
`find / -links +1 -type f`
100. 用三剑客一句话完成“日志中UA含 `bot` 的IP去重后倒序访问次数”
`awk '$0~bot{ip=$1} END{for(i in ip) print ip[i],i}' log | grep bot | sort -nr`
—
附:速记口诀
– grep 专管“找”,正则最拿手;
– sed 专管“改”,行替换最快;
– awk 专管“算”,列/数组/报表全能。
把上面100题刷完,90%的“Linux三剑客”面试题可直接秒答。祝你收割offer!






