一、sed 和变量联动是替换类操作的常见写法¶
原笔记用 IP 段替换做了一个非常典型的例子:
cat ip.txt
10.0.0.5
10.0.0.6
10.0.0.7
10.0.0.8
10.0.0.9
src=10.0.0
dst=172.16.1
sed "s#$src#$dst#g" ip.txt
这里有两个值得记住的点:
sed里使用 Shell 变量时,要用双引号而不是单引号。- 分隔符不一定非要用
/,像#这种写法在处理路径和 IP 时更方便。
二、awk 最基础的能力是按列取值¶
原笔记给出的几个例子,几乎覆盖了日常最常见的列提取写法。
2.1 提取 /etc/passwd 指定行和列¶
awk -F: 'NR>=2 && NR<=9{print $1,$3}' /etc/passwd
这里:
-F:指定冒号为分隔符NR表示当前行号$1、$3表示第 1 列和第 3 列
2.2 条件匹配后取最后一列¶
awk -F: '$1=="root"{print $NF}' /etc/passwd
$NF 表示最后一列,是 awk 里非常高频的写法。
2.3 通过变量传值给 awk¶
name=root
awk -F: -vn=$name '$1==n{print $NF}' /etc/passwd
这说明 awk -v 不只是用来做计算,也是 Shell 和 awk 传参的通用方式。
三、awk 也能处理判断和循环¶
3.1 判断磁盘是否超过阈值¶
原笔记给出的示例是:
df -h | awk -F"[ %]+" '$NF=="/" && $(NF-1)>=80 {print "磁盘空间不足"}'
这个例子很适合理解 awk 里的几个基础点:
- 分隔符可以是正则
$NF是最后一列$(NF-1)是倒数第二列- 条件满足时可以直接
print
3.2 awk 里的循环¶
awk 'BEGIN{for(i=1;i<=100;i++) sum=sum+i; print sum}'
也就是说,awk 不只是“按列打印”,它本身就具备轻量级脚本语言的特征。
四、awk 数组和 Shell 数组有什么不同¶
原笔记特别强调:
- Shell 数组默认以下标数字为主
awk数组是关联数组,下标可以是字符串
这就是为什么做日志统计、去重计数、分类汇总时,awk 往往比纯 Shell 更合适。
4.1 创建和读取 awk 数组¶
awk 'BEGIN{array[0]="lidao996";array["lidao"]=996;array[110]="sos";print array[0]}'
4.2 遍历 awk 数组¶
awk 'BEGIN{
array[0]="lidao996"
array["lidao"]=996
array[110]="sos"
for (n in array)
print n, array[n]
}'
这里的 for (n in array) 是 awk 数组统计最核心的语法。
五、案例:统计每个域名出现了多少次¶
原笔记给出的 URL 统计案例,非常适合理解 awk 数组的优势:
awk -F'/+' '{url[$2]++} END{for(name in url) print name, url[name]}' /server/files/url.txt
思路其实很简单:
1、用 -F'/+' 把 URL 分隔开。
2、取域名所在的 $2 作为数组下标。
3、每读到一次就加 1。
4、最后统一输出。
这种模式几乎可以直接迁移到:
- 域名访问次数统计
- 用户行为次数统计
- 错误码次数统计
- IP 访问次数统计
六、案例:统计访问日志中每个 IP 的总流量¶
原笔记还给出了一个“去重求和”的例子:
awk '{liu[$1]=liu[$1]+$10} END{for(ip in liu) print ip, liu[ip]}' /var/log/nginx/access.log-20240104 | sort -rnk2 | head
这个例子说明:
$1可以作为 IP 地址键$10可以作为流量值- 每行都把流量加到对应 IP 上
- 最后再排序取 Top N
相比先 sort | uniq 再做其他处理,awk 这种“边读边统计”的方式通常更直接。
七、awk 和 Shell 语法该怎么对照理解¶
原笔记最后给了一组对照关系,非常适合复习:
- Shell 的
if ... then ... fi,对应awk里的if (...) { ... } - Shell 的
for((i=1;i<=10;i++)),对应awk的for(i=1;i<=10;i++) - Shell 的通用列表循环
for n in list,对应awk的数组循环for (n in array)
一旦把这些对应关系建立起来,学习三剑客时就不会觉得它和 Shell 是两套完全割裂的东西。
八、这一篇内容为什么放在最后¶
因为 Shell 自动化真正进阶的节点,不是多会几个系统命令,而是开始能把日志、配置、文本结果快速提炼成结构化数据,再根据结果做判断和处理。
sed 负责替换,awk 负责提取、判断和统计,Shell 负责把这些能力组织成完整流程。三者组合起来,才是自动化运维里最常见、也最实用的一套文本处理工具链。