微信扫描下方二维码关注公众号带你玩转Linux
1. awk概述
四剑客 | 特点 | 擅长 |
---|---|---|
find | 查找文件 | 查找文件 |
grep/egrep | 过滤 | 过滤速度更快 |
sed | 过滤,取行,替换,删除 | 替换,修改文件内容,取行 |
awk | 过滤,取行,取列,统计计算,判断,循环... | 取列,取行,统计计算 |
- awk是一个语言,叫做单行脚本
1.1 格式
取出/etc/passwd中的第1行的第1列,第3列和最后1列
awk -F: 'NR==1{print $1,$3,$NF}' /etc/passwd
awk 选项 '条件{动作}' /etc/passwd
条件 找谁
动作 干啥
1.2 执行流程
2. 取行
2.1 案例01: 取出/etc/passwd的第一行
awk 'NR==1{print $0}' /etc/passwd
root:x:0:0:root:/root:/bin/bash
NR Number of Record 记录号,行号。
== 表示等于
{print $0} 输出整行内容 $0表示当前行的内容
上面仅取行,还可以简写为awk 'NR==1' /etc/passwd
2.2 案例02:取出第2行到第5行的内容
awk 'NR>=2' /etc/passwd
awk 'NR>=2 && NR<=5' /etc/passwd
>= 表示大于等于
&& 表示并且
|| 表示或者
awk常用的运算符 | 说明 |
---|---|
== | 等于 |
!= | 不等于 |
> | 大于 |
>= | 大于等于 |
< | 小于 |
<= | 小于等于 |
&& | 并且 & and符 |
|| | 或者 |
2.3 案例03: 过滤出/etc/passwd文件中包含root或nobody的行
awk '/root|nobody/' /etc/passwd
2.4 案例04:从包含root的行到包含nobody的行
awk '/root/,/nobody/' /etc/passwd
3. 取列
3.1 案例05:使用awk取出ls -lh 的大小列和最后一列
[root@Gq ~]# ls -lh /etc/hosts
-rw-r--r-- . 1 root root 158 6月 7 2013 /etc/hosts
[root@Gq ~]# ls -lh /etc/hosts |awk '{print $5,$9}'
158 /etc/hosts
[root@Gq ~]# ls -lh /etc/hosts |awk '{print $5,$NF}'
158 /etc/hosts
awk中去列的时候说明:
- $数字,表示取列,$1 第1列 $0表示这一行。
- $NF 最后1列
- NF Number of Field 每行有多少列
- $(NF-1) 取出倒数第2列,一般用于正向取发生变化或数字过大
过滤出日志中密码错误的ip地址 grep failed secure-20161219 |head |awk '{print $(NF-3)}'
3.2 案例06:取出/etc/passwd中的第1列,第3列和最后一列
awk取列的时候,默认是通过空白字符进行分割的。
空白字符:空格,连续空格,tab健。
但是一些时候使用默认分隔符不够了,需要我们手动指定分隔符,通过-F选项指定。
未来我们想快速取出想要的内容,选择趁手工具(选好分隔符)
选择分割符建议:看你目标两边是啥。
awk -F':' '{print $1,$3,$NF}' /etc/passwd|column -t
3.3 案例07:指定复杂分隔符取出ip
ip a s eth0|awk 'NR==3'
inet 10.0.0.200/24 brd 10.0.0.255 scope global noprefixroute eth0
温馨提示:inet前面有4个空格
遇到空格或/就切一刀,所以4个空格切4刀,ip是第6列
[root@Gq ~]# ip a s eth0 | awk 'NR==3' |awk -F'[/]' '{print $6}'
10.0.0.200
遇到连续的空格或/就切一刀,所以4个空格切1刀,所以ip是第3列
[root@Gq ~]# ip a s eth0 | awk 'NR==3' |awk -F'[/]+' '{print $3}'
10.0.0.200
4.取行与取列
4.1 案例08:取行+取列 取ip地址
awk 选项 '条件{动作}' /etc/passwd
ip a s eth0 |awk -F'[ /]+' 'NR==3{print $3}'
10.0.0.200
-
额外案例 : 取出权限部分 stat /etc/hosts 的 0644 部分
stat /etc/hosts |awk -F '[/(]' 'NR==4{print $2}'
stat /etc/hosts |awk -F '[^0-9]+' 'NR==4{print $2}'
4.2 ⭐⭐⭐⭐⭐案例09: 对列的判断取出/etc/passwd 文件中第3列大于1000的行,取出这行的第1列,第3列和最后一 列
- 条件:$3 第3列用户的uid
- 动作: 第1列,第3列和最后一列
awk 选项 '条件{动作}' /etc/passwd
awk -F':' '$3>1000' /etc/passwd
awk -F':' '$3>1000{print $1,$3,$NF}' /etc/passwd |column -t
oldboy 1001 /bin/bash
nginx 1002 /sbin/nologin
通过 awk 实现对某一列进行判断 .
4.3 ⭐案例10: 如果系统swap使用超过0则输出"异常系统开始占用swap"
条件
条件1:过滤出sqap
条件2:第3列大于0
动作
输出这句话
free |awk '/Swap/ && $3 >= 0'
Swap: 2097148 0 2097148
free |awk '/Swap/ && &3 >= 0 {print "异常系统开始占用swap"}'
异常系统开始占用swap
4.4 ⭐⭐⭐⭐⭐案例11: 过滤出/etc/passwd第4列的数 字是以0或1开头的行,输出第1列,第3列
- 之前^ 或$ 表示某一行的开头或结尾。
- 在awk中因为awk可以取列,通过列可以过滤某一列包含什么…… 过滤某一列中以xxxxx开头或结尾。
awk -F':' '$4 ~ /^[01]/' /etc/passwd
条件:第4列的数字是以0或1开头 $4 ~ /^[01]/
动作:输出第1列和第3列
awk -F':' '$4 ~ /^[01]/ {print $1,$3}' /etc/passwd
温馨提示 awk 通过$3 ~
- ~表示包含的意思 $1 ~ /root/ 表示第1列中包含root
- !~ 表示不包含
5. awk统计与计算
5.1 统计次数
- 仅仅需要统计出现了多少次,出现了多少个。可以使用wc -l方式
i=i+1 i值 i=i+1值
第1行 空/0 i=0+1 i=1
第2行 1 i=1+1 i=2
第3行 2 i=2+1 i=3
i=i+1 计数公式.
awk '{i=i+1} END{print i}' /etc/passwd
26
END{} 内容会在 awk 读取完成文件的时候执行 .END{} 一般用于输出执行结果 .i=i+1 === i++
5.2 计算总和
seq 10 > num.txt计算num.txt每一行的数字的总和
awk '{i=i+$1}END{print i}' num.txt
55
分析执行流程
$1 i i=i+$1 第1行 1 空 i=0+1 i=1 第2行 2 1 i=1+2 i=3 第3行 3 3 i=3+3 i=6 第4行 4 6 i=6+4 i=10
i=i+$xxx === i+=$xxx