本博文目录索引
一、操作符
(一)算术操作符
算术操作符 | 含义 | 备注 |
---|---|---|
x+y | 加法 | |
x-y | 减法 | |
x*y | 乘法 | |
x/y | 除法 | |
x^y | x的y次幂 | |
x%y | x对y取余数 | 余数范围:[0,y-1]闭区间 |
-x | 将x转换为负数 | |
+x | 将x转换为数值 |
(二)字符串操作符
没有符号的操作符,字符串连接
(三)赋值操作符
赋值操作符 | 等值写法 | 含义 | 备注 |
---|---|---|---|
x=y | y值赋值给x | ||
x+=y | x=x+y | 加法 | |
x-=y | x=x-y | 减法 | |
x*=y | x=x*y | 乘法 | |
x/=y | x=x/y | 除法 | |
x%=y | x=x%y | x对y取余数 | 余数范围:[0,y-1]闭区间 |
x^=y | x=x^y | x的y次幂 | |
i++ | i,i=i+1 | 先输出i,然后i+1 | 引用表达式的输出值:i |
++i | i=i+1,i | 先i+1,然后再输出i | 引用表达式的输出值:i+1 |
i– | i,i=i-1 | 先输出i,然后i-1 | 引用表达式的输出值:i |
–i | i=i-1,i | 先i-1,然后再输出i | 引用表达式的输出值:i-1 |
举例:++i与i++的区别
[root@Alvin ~]# awk 'BEGIN{i=0;print ++i,i}'
[root@Alvin ~]# awk 'BEGIN{i=0;print i++,i}'
特别注意!
++i 表示先自加一,然后再被引用;被引用的值是 i+1
i++ 表示先被引用,然后再自加一;被引用的值是 i
STDOUT:
1 1被引用的值是 i+1:i+1=0+1=1
0 1被引用的值是 i:i=0
(四)比较操作符
比较操作符 | 判断…是否成立 | 类比Shell的比较操作符 | 说明 |
---|---|---|---|
x==y | x值等于y值 | -eq | 【equal】 |
x!=y | x值不等于y值 | -ne | 【not equal】 |
x>y | x值大于y值 | -gt | 【greater than】 |
x>=y | x值大于等于y值 | -ge | 【greater equal】 |
x | x值小于y值 | -lt | 【less than】 |
x<=y | x值小于等于y值 | -le | 【less equal】 |
举例:过滤 /dev/sd 开头的行,取出空间利用率大于10的行
[root@Alvin ~]# df -h | awk -F% '/^\/dev\/sd/' | awk '$5>10'
STDOUT:
设备名 分区总大小 已用空间 剩余空间 空间利用率 挂载点
/dev/sda2 50G 1.4G 49G 3% /
/dev/sda1 1014M 119M 896M 12% /boot
(五)模式匹配符
模式匹配符 | 判断…是否成立 |
---|---|
~ | 左边和右边匹配包含 |
!~ | 左边和右边不匹配包含 |
注意!
(1)“匹配包含”表示右边包含左边,属于包含关系,不需要完全匹配!
(2)右边写pattern表达式,用来匹配左边
举例一:过滤 /dev/sd 开头的行,取出第1、5、6列
[root@Alvin ~]# df -h | awk '$0 ~ /^\/dev\/sd/{print $1,$5,$6}'
STDOUT:
设备名 分区利用率 挂载点
/dev/sda1 4% /boot
/dev/sda2 3% /
[此处省略更多信息]
举例二:取出以 /dev/sd 开头的行
[root@Alvin ~]# df -h | awk '$0 ~ /^\/dev\/sd/'
注意
此处相当于省略了action语句 {print $0}
STDOUT:
设备名 分区总大小 已用空间 剩余空间 空间利用率 挂载点
/dev/sda2 50G 1.4G 49G 3% /
[此处省略更多信息]
(六)逻辑操作符
逻辑操作符 | 含义 | 使用说明 |
---|---|---|
&& | 逻辑与 | 全真为真,有假则假 |
|| | 逻辑或 | 有真为真,全假才假 |
! | 逻辑非 | 遇真变假,遇假变真 |
举例一:取出UID大于等于0且小于等于10的行
[root@Alvin ~]# awk -F: '$3>=0 && $3<=10' /etc/passwd
注意:此处相当于省略了action语句 {print $0}
STDOUT:
用户名:密码:UID:GID:描述:家目录:默认Shell
root:x:0:0:root:/root:/bin/bash
[此处省略更多信息]
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
举例二:取出UID小于1000的行
[root@Alvin ~]# awk -F: '!($3>=1000)' /etc/passwd
注意:此处相当于省略了action语句 {print $0}
STDOUT:
用户名:密码:UID:GID:描述:家目录:默认Shell
root:x:0:0:root:/root:/bin/bash
[此处省略更多信息]
chrony:x:998:996::/var/lib/chrony:/sbin/nologin
(七)三目表达式
selector ? if-true-expression : if-false-expression
含义:
判断selector是否为真?
如果为真,执行if-true-expression
否则为假,执行if-false-expression
举例:通过UID判断用户属于“普通用户”还是“系统管理员/系统用户”
[root@Alvin ~]# awk -F: '{$3>=1000?userType="CommonUser":userType="SysAdmin/SysUser";printf "%-16s:%-s\n",$1,userType}' /etc/passwd
STDOUT:
用户名 : 判断结果
root :SysAdmin/SysUser
systemd-network :SysAdmin/SysUser
[此处省略更多信息]
(八)awk小坑:空值
、0
、非零非空值
awk中的值 | 真假? | 取反后的值 | 真假? |
---|---|---|---|
空值 |
False | 1 |
True |
0 |
False | 1 |
True |
非零非空值 |
True | 0 |
False |
二、PATTERN过滤匹配行
(一)未指定pattern条件
空模式,匹配每一行
举例:取出当前系统的所有用户名
[root@Alvin ~]# awk -F: '{print $1}' /etc/passwd
默认相当于匹配所有行,'$0 ~ {print $1}'
STDOUT:
所有用户名
root
bin
[此处省略更多信息]
(二)/regular expression/
模式匹配
仅处理能够被pattern模式匹配到的行,需要用一对 / 括起来
举例:匹配以 UUID 开头的所有行
[root@Alvin ~]# awk '/^UUID/' /etc/fstab
STDOUT:
设备文件的UIID 挂载点 文件系统类型 挂载选项 备份次序 文件系统检查完整性的次序
UUID=7d2d8544-e30b-45ad-8473-07a9fc18a567 / xfs defaults 0 0
[此处省略更多信息]
(三)relational expression
关系表达式
仅当关系表达式的结果为 True 才会被处理
结果 | 判断为 |
---|---|
空值 |
False |
0 |
False |
非零非空值 |
True |
举例:匹配以 /bin/bash 为默认Shell的用户,显示其用户名
[root@Alvin ~]# awk -F: '$NF=="/bin/bash"{print $1,$NF}' /etc/passwd
STDOUT:
用户名 /bin/bash
root /bin/bash
[此处省略更多信息]
(四)line ranges
行范围
1、通过pattern匹配startline(起始行)和endline(终止行)中间的所有行
/pattern1/
表示匹配startline(起始行)
/pattern2/
表示匹配endline(终止行)
不支持直接给出数字格式,必须写正则表达式
举例:取出从“以root开头”到“以nobody开头”之间的所有行
[root@Alvin ~]# awk -F: '/^root\>/,/^nobody\>/{print $1}' /etc/passwd
STDOUT:
用户名
root
[此处省略更多信息]
nobody
2、透过取NR交集,取出指定行
通过指定NR范围,然后取NR交集,实现支持以数字格式取出指定行
举例:取出“第10行”到“第20行”之间的所有行
[root@Alvin ~]# awk -F: '(NR>=10&&NR<=20){print NR,$1}' /etc/passwd
STDOUT:
行号 用户名
10 operator
[此处省略更多信息]
20 ntp
(五)BEGIN/END
模式
BEGIN{}:仅在开始处理文本内容之前,可以独立存在
END{}:仅在文本内容处理完成后,必须紧跟在 pattern{action;…} 语句后
举例:使用BEGIN/END打印表头
[root@Alvin ~]# awk -F: 'BEGIN{print "username:uid"}(NR==1){print $1,$3}END{print "EOF"}' /etc/passwd
STDOUT:
username:uid打印表头
root 0用户名 UID
EOF打印结束标志
(六)关系表达式的典型用法解析
执行过程解析
读取到第?行 | i的初始值 | i值取反之后 | 条件为真/假? | 打印? |
---|---|---|---|---|
第一行“1” | 空值 | 1 | True | 打印第一行✅:1 |
第一行“2” | 1 | 0 | False | 不打印第二行 |
第一行“3” | 0 | 1 | True | 打印第三行✅:3 |
第一行“4” | 1 | 0 | False | 不打印第四行 |
第一行“5” | 0 | 1 | True | 打印第五行✅:5 |
第一行“6” | 1 | 0 | False | 不打印第六行 |
第一行“7” | 0 | 1 | True | 打印第七行✅:7 |
第一行“8” | 1 | 0 | False | 不打印第八行 |
第一行“9” | 0 | 1 | True | 打印第九行✅:9 |
第一行“10” | 1 | 0 | False | 不打印第十行 |
举例:打印奇数行
[root@Alvin ~]# seq 10 | awk 'i=!i'
STDOUT:
奇数行
1
3
5
7
9
补充:sed打印奇数行
[root@Alvin ~]# seq 10 | sed -n '1~2p'
1~2p
表示从第一行开始、每次步进两行
STDOUT:
奇数行
1
3
5
7
9