一、awk能干什么
awk其实是一个变成语言,他能:
- 取行
- 取列
- 模糊过滤,区间过滤
- 判断比较(字符串,数字对比)
- 支持 if判断,for循环,while循环 ,数组等编程
- 格式化输出(例如指定分隔符)
二、awk的语法结构
- awk ‘模式’ file
例如: awk 'NR==2' file
- awk ‘模式+动作’ file 模式+动作 也可理解为 找谁+干嘛
例如: awk 'NR>=2{print $3}' file
模式:BEGIN提前模式 awk -F: ‘BEGIN{print “用户名称”}{print $1}’ passwd提前打印用户名称
注意:awk默认支持扩展正则,不需要加参数
注意:awk是一行一行过滤,一行一行打印输出
三、awk常用的的符号和变量
选项参数 | 说明 |
---|---|
-F 指定分隔符 | -F: -F “:” 指定:为分隔符 |
-F “[:/]” :或者 / 为分隔符 | |
-F “:|/” :或者 / 为分隔符 | |
-F “:/” 整体以:/为分隔符 | |
-Fab -F “ab” 以ab作为分隔符 | |
==选择分隔符建议: 看你目标两边是啥.== |
变量 | 说明 |
---|---|
$ | 表示列,$1 、$2 、$3 …:当前行的第1个、第2个、第3个字段,以此类推。$0 :当前行的全部内容 |
NF | 最后一列,表示每一行最后一列的列号 比如最后一列是第8列 $NF就是$8 |
NR | 表示行,通过NR找出指定的行 awk ‘NR==5’ file |
END | 最后一行 |
符号 | 简单例子 |
---|---|
== 等于 | awk ‘NR==2’ file 过滤第二行 |
!= 不等于 | awk ‘NR!=2’ file |
> 大于 | awk ‘NR>2’ file |
>= 大于等于 | awk ‘NR>=2’ file |
< 小于 | awk ‘NR<2’ file |
<= 小于等于 | awk ‘NR<=2’ file |
&& 并且 & and符 | awk ‘NR>3&&NR<5’ file |
|| 或者 | awk ‘NR==1||NR==5’ file |
~ 波浪线 模式匹配 | 匹配正确符合,则默认输出 |
四、awk案例
1.awk取行
语法结构:
sed -n '3p' file
awk 'NR==3' file
awk默认就是输出的动作 如果只输出则不需要加print
[root@oldboyedu ~]# awk 'NR==3{print}' passwd
root:x:0:0:root:/root:/bin/bash
[root@oldboyedu ~]# awk 'NR==3' passwd
root:x:0:0:root:/root:/bin/bash
NR awk的内置变量 存储着每行的行号
符号
== 等于第几行
!= 不等与
> 大于第几行
>= 大于等于第几行
< 小于第几行
<= 小于等于第几行
&& 并且
|| 或者
# 案例1 awk取出文件的第3行
[root@oldboyedu ~]# awk 'NR==3' awk.txt
3 daemon:x:2:2:daemon:/sbin:/sbin/nologin
# 案例2 awk取出文件大于3的行
[root@oldboyedu ~]# awk 'NR>3' awk.txt
4 adm:x:3:4:adm:/var/adm:/sbin/nologin
5 lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
6 sync:x:5:0:sync:/sbin:/bin/sync
# 案例3 awk取出文件中小于3的行
[root@oldboyedu ~]# awk 'NR<3' awk.txt
1 root:x:0:0:root:/root:/bin/bash
2 bin:x:1:1:bin:/bin:/sbin/nologin
# 案例4 awk取出文件中小于等于3的行
[root@oldboyedu ~]# awk 'NR<=3' awk.txt
1 root:x:0:0:root:/root:/bin/bash
2 bin:x:1:1:bin:/bin:/sbin/nologin
3 daemon:x:2:2:daemon:/sbin:/sbin/nologin
# 案例5 awk取出不等于1的行
[root@oldboyedu ~]# awk 'NR!=1' awk.txt
2 bin:x:1:1:bin:/bin:/sbin/nologin
3 daemon:x:2:2:daemon:/sbin:/sbin/nologin
4 adm:x:3:4:adm:/var/adm:/sbin/nologin
5 lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
6 sync:x:5:0:sync:/sbin:/bin/sync
# 案例6 查找出大于3并且小于5的行
[root@oldboyedu ~]# awk 'NR>3&&NR<5' awk.txt
4 adm:x:3:4:adm:/var/adm:/sbin/nologin
# 案例7 输出文件中的第1行和第5行
[root@oldboyedu ~]# awk 'NR==1||NR==5' awk.txt
1 root:x:0:0:root:/root:/bin/bash
5 lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
# 案例8 输出文件中的第大于第2行的最后一列内容
[root@oldboyedu ~]# awk -F: 'NR>2{print $NF}' awk.txt
/sbin/nologin
/sbin/nologin
/sbin/nologin
/bin/sync
# 案例9 查找文件中第1列等于root的行
[root@oldboyedu ~]# awk -F: '$1=="root"' awk.txt
root:x:0:0:root:/root:/bin/bash
# 案例10 使用正则匹配字符串,匹配第一列以ro开头的行
[root@oldboyedu ~]# awk -F: '$1 ~ "^ro" ' awk.txt
root:x:0:0:root:/root:/bin/bash
# 案例11 匹配最后一列以n结尾的行
[root@oldboyedu ~]# awk -F: '$NF~"n$"' awk.txt
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
# 案例12 取出不包含root的行
# awk '$0 !~ /root/' awk.tx
[root@oldboyedu ~]# awk '!/root/' awk.txt
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
# 案例13 取出不以ro开头的行
# awk '$0 !~ /^ro/' awk.txt
[root@oldboyedu ~]# awk '!/^ro/' awk.txt
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/root/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
# 案例14 passwd 第3列等于0的行
[root@oldboyedu ~]# awk -F: '$3==0' awk.txt
root:x:0:0:root:/root:/bin/bash
# 案例15 passwd 第3列大于5的行
[root@oldboyedu ~]# cat awk.txt
root
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/root/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
[root@oldboyedu ~]# awk -F: '$3>5' awk.txt
2.awk取列
语法结构:
awk '{print $1}' file # 取出文件中的第1列
-F指定分隔符
默认按照空格或者tab键分隔成列
如果没有空格或者tab键,awk会将整行看成一列
在awk中一切在动作中的字符串都被看做是变量,加上双引号则视为普通的字符串
表示每一行最后一列的列号 awk是一行一行执行 比如最后一列是第8列 $NF就是$8
awk内置变量
$0 # 表示整行
$1 # 表示文件的第1列
$2 # 表示文件的第2列
, # 逗号表示空格
NF # 表示每一行最后一列的列号
案例文件awk.txt
a
a b
a b c
b c d c
# 案例1 取出文件中的第一列
[root@oldboyedu ~]# awk -F: '{print $1}' awk.txt
root
root
bin
daemon
adm
lp
sync
# 案例2 取出文件中的第3列
[root@oldboyedu ~]# awk -F: '{print $3}' awk.txt
0
1
2
3
4
5
# 案例3 取出文件中的第1和第3列
[root@oldboyedu ~]# awk -F: '{print $1,$3}' awk.txt
root
root 0
bin 1
daemon 2
adm 3
lp 4
sync 5
# 案例4 取出文件中的第1和第3列并且以逗号分隔
[root@oldboyedu ~]# awk -F: '{print $1","$3}' awk.txt
root,0
bin,1
daemon,2
adm,3
lp,4
sync,5
# 案例5 取出文件中的第3列和第1列
[root@oldboyedu ~]# awk -F: '{print $1 $3}' awk.txt
root0
bin1
daemon2
adm3
lp4
# 案例6 取出文件中的最后1列 分别使用NF和$
[root@oldboyedu ~]# awk -F: '{print $NF}' awk.txt
/bin/bash
/sbin/nologin
/sbin/nologin
/sbin/nologin
/sbin/nologin
/bin/sync
# 案例7 获取文件的倒数第2列
[root@oldboyedu ~]# awk -F: '{print $(NF-1)}' awk.txt
/root
/bin
/sbin
/var/adm
/var/spool/lpd
/sbin
# 案例8 使用$打印出文件的全部内容
[root@oldboyedu ~]# awk '{print $0}' awk.txt
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
# 案例9 df -h取出百分比
[root@oldboyedu ~]# df -h | awk '{print $(NF-1)}'
Mounted
0%
0%
2%
0%
# 案例10 取出passwd文件中用户名
[root@oldboyedu ~]# awk -F: '{print $1}' awk.txt
root
bin
daemon
adm
lp
sync
# 案例11 取出passwd中的命令解释器
[root@oldboyedu ~]# awk -F: '{print $NF}' awk.txt
/bin/bash
/sbin/nologin
/sbin/nologin
/sbin/nologin
/sbin/nologin
/bin/sync
# 案例12 取出passwd中的第一个和最后一列 用户名和bash解释器
[root@oldboyedu ~]# awk -F: '{print $1,$NF}' awk.txt
root /bin/bash
bin /sbin/nologin
daemon /sbin/nologin
adm /sbin/nologin
lp /sbin/nologin
sync /bin/sync
# 案例13 请问这个命令 awk -F "[:/]+" 在passwd中分隔了几次
只要有:/连着就只算一次
# 案例14 输出文件中的第大于第2行的最后一列内容
awk -F: 'NR>3 {print $NF}' awk.txt
# 案例15 输出文件中第2行的第2列
[root@oldboyedu ~]# awk -F: 'NR==2{print $2}' awk.txt
x
# 案例16 passwd中指定分隔符输出第1行的第一列
[root@oldboyedu ~]# awk -F: 'NR==1{print $1}' awk.txt
root
# 案例17 过滤出secure日志中密码错误的ip地址.
awk '/sshd/ && /authentication failure/ {print $14}' /var/log/secure*
# 案例18 只要名字和成绩 统计成绩 1.统计大于等于90分的 2.统计小于60分的 3.统计60-89之间的 4.按照成绩逆序排序
[root@oldboyedu ~]# awk '$3>90' name.txt
[root@oldboyedu ~]# awk '$3<60' name.txt
[root@oldboyedu ~]# awk '$3>60&&$3<90' name.txt
[root@oldboyedu ~]# awk '$3>60&&$3<90' name.txt | sort -rnk1
# 案例19 ip a 用awk取出ip
ip a | awk 'NR==9{print $2}'|awk -F/ '{print $1}'
# 案例20 取出权限部分 stat /etc/hosts的0644部分
stat /etc/hosts | awk -F "[/(]" 'NR==4 {print $2}'
# 案例21 取出/etc/passwd文件中第3列大于1000的行,取出这行的第1列,第3列和最后一列(一条命令)
awk -F: '$3>1000 {print $1,$3,$NF}' passwd
# 案例22 如果系统swap使用超过0则输出"异常系统开始占用swap"
free | awk -r 'NR==3 && $3>=0 {print 异常系统开始占用swap}'
3.模糊过滤,区间过滤
语法结构: 支持正则
sed -n '//p' file
awk '//' file # 模糊查找文件中的字符串
awk '//,//' file # 区间范围
awk默认就是输出的动作 如果只输出则不需要加print
# 案例1 找出包含root的行
sed -n '/root/p' passwd
awk '/root/' passwd
# 案例2 找出包含bash的行
awk '/bash/' passwd
# 案例3 找出以a开头的行
awk '/^a/' passwd
# 案例4 找出文件中包含root或者和adm的行
awk '/root|adm/' passwd
# 案例5 查找出以s或者b开头的行
awk '/^s|^b/' passwd
# 案例6 按照区间过滤 过滤日志中的时间范围
awk '/Nov 20 18:01:07/,/Nov 20 18:43:59/' /var/log/secure
# 案例7 找出adm到root开头的行
awk '/^adm/,/^root/' passwd
# 案例8 过滤出3-5行的内容
awk 'NR<=5 && NR>=3'
# 案例9 df -h找出tmp和run结尾的行
df -h | awk '/tmp$|run$/'
# 案例10 df -h找出tmp到run结尾的行
df -h | awk '/tmp$/,/run$/'
# 案例11 输出包含adm的行的第4列
awk '/adm/ {print $4}'
- awk数值运算
- 支持加减乘除
awk '{print 10+1 }' 7.txt
11
awk '{print 3*3}' 7.txt
9
5.awk的~匹配
# 案例1 过滤出/etc/passwd第4列的数字是以0或1开头的行,输出第1列,第3列
awk -F: '$4 ~ "^[01]" {print $1,$3}' passwd
# 案例2 使用正则匹配字符串,匹配第一列以ro开头的行
awk -F: '$1~"^ro"' passwd
# 案例3 匹配最后一列以n结尾的行
awk -F: '$NF~"n$"' passwd
# 案例4 取出不包含root的行
awk -F: '/[^root]/' passwd
# 案例5 取出不以ro开头的行
awk -F: '$1 !~ "^ro" ' passwd