awk 也是一个非常棒的数据处理工具。
awk 用来截取符合条件的列。
awk 的功能远比cut强大;甚至可以称之为awk编程。
格式:
awk '条件1{动作1} 条件2{动作2} ...' filename
含义:
[userwin@MiWiFi-R3L-srv ~]$ df -h 文件系统 容量 已用 可用 已用% 挂载点 /dev/mapper/centos-root 18G 2.0G 16G 12% / devtmpfs 479M 0 479M 0% /dev tmpfs 489M 0 489M 0% /dev/shm tmpfs 489M 6.7M 483M 2% /run tmpfs 489M 0 489M 0% /sys/fs/cgroup /dev/sda1 497M 107M 391M 22% /boot tmpfs 98M 0 98M 0% /run/user/1000 # 想使用cut 命令获取上面内容的第二列内容;结果出乎意料了吧? [userwin@MiWiFi-R3L-srv ~]$ df -h | cut -d " " -f2 # 文件系统后面列后面跟多个空格,cut命令无法识别。awk命令刚好解决这个问题。 [userwin@MiWiFi-R3L-srv ~]$ df -h | awk '{print $2}' 容量 18G 479M 489M 489M 489M 497M 98M
文件系统后面列后面跟多个空格,cut命令无法识别;如下图:
获取第二列和第六列 df -h | awk ‘{print $2 “\t” $6}’
点引号后面直接跟{print 此处省略了条件。默认为true。
awk 最常使用的动作!透过 print 的功能将栏位数据列出来!栏位的分隔则以空白键或 [tab] 按键来隔开
[userwin@MiWiFi-R3L-srv ~]$ df -h | awk '{print $2 "\t" $6}' 容量 挂载点 18G / 479M /dev 489M /dev/shm 489M /run 489M /sys/fs/cgroup 497M /boot 98M /run/user/1000
在awk语句中,printf 输出不会换行,需要手动加入\n
且看下面示例:
[userwin@MiWiFi-R3L-srv ~]$ df -h | awk '{print $2 "\t" $6}' 容量 挂载点 18G / 479M /dev 489M /dev/shm 489M /run 489M /sys/fs/cgroup 497M /boot 98M /run/user/1000 [userwin@MiWiFi-R3L-srv ~]$ df -h | awk '{printf $2 "\t" $6}' 容量 挂载点18G /479M /dev489M /dev/shm489M /run489M /sys/fs/cgroup497M /boot [userwin@MiWiFi-R3L-srv ~]$ df -h | awk '{printf $2 "\t" $6 "\n"}' 容量 挂载点 18G / 479M /dev 489M /dev/shm 489M /run 489M /sys/fs/cgroup 497M /boot 98M /run/user/1000
# 查看 [userwin@MiWiFi-R3L-srv ~]$ df -h 文件系统 容量 已用 可用 已用% 挂载点 /dev/mapper/centos-root 18G 2.0G 16G 12% / devtmpfs 479M 0 479M 0% /dev tmpfs 489M 0 489M 0% /dev/shm tmpfs 489M 6.7M 483M 2% /run tmpfs 489M 0 489M 0% /sys/fs/cgroup /dev/sda1 497M 107M 391M 22% /boot tmpfs 98M 0 98M 0% /run/user/1000 # 获取sda1 行 [userwin@MiWiFi-R3L-srv ~]$ df -h | grep "sda1" /dev/sda1 497M 107M 391M 22% /boot # 获取第5列 [userwin@MiWiFi-R3L-srv ~]$ df -h | grep "sda1" | awk '{print $5}' 22% # 使用cut截取%前面的数值 [userwin@MiWiFi-R3L-srv ~]$ df -h | grep "sda1" | awk '{print $5}' |cut -d '%' -f1 22
awk命令: 每一行的每个栏位都是有变量名称的,那就是 $1, $2… 等变量名称 每个栏位就对应的每一列。$1指第一列;
$0 代表『一整列数据』的意思
变量名称 | 代表意义 |
---|---|
NF | 每一行 ($0) 拥有的栏位总数 |
NR | 目前 awk 所处理的是『第几行』数据 |
FS | 目前的分隔字节,默认是空白键 |
# 查看passwd文件中包含/bin/bash 的内容 [userwin@MiWiFi-R3L-srv ~]$ cat /etc/passwd | grep "/bin/bash" root:x:0:0:root:/root:/bin/bash userwin:x:1000:1000:userwin:/home/userwin:/bin/bash # 使用awk自定义分隔符获取1,3两列 [userwin@MiWiFi-R3L-srv ~]$ cat /etc/passwd | grep "/bin/bash" | awk '{FS=":"} {print $1 "\t" $3}' root:x:0:0:root:/root:/bin/bash userwin 1000
第一个列为什么没有执行分割呢?
看一下awk的执行顺序,先读入第一行,读完才执行FS=:这个分隔符,故而出现如下图情况
需要使用BEGIN命令添加一个空行,如下
[userwin@MiWiFi-R3L-srv ~]$ cat /etc/passwd | grep "/bin/bash" |\ awk 'BEGIN{FS=":"} {print $1 "\t" $3}' root 0 userwin 1000
BEGIN 处理数据前加入内容
[userwin@MiWiFi-R3L-srv ~]$ df -h | grep "sda1" | awk 'BEGIN{print "sda1的使用率为:"}{print $5}' sda1的使用率为: 22% [userwin@MiWiFi-R3L-srv ~]$ df -h | grep "sda1" | awk 'BEGIN{printf "sda1的使用率为:"}{print $5}' sda1的使用率为:22%
BND 处理数据后加入内容
[userwin@MiWiFi-R3L-srv ~]$ df -h | grep "sda1" | awk 'BEGIN{print "sda1的使用率为:"} END{print "命令执行完 毕!!"}{print $5}' sda1的使用率为: 22% 命令执行完毕!!
运算单元 | 代表意义 |
---|---|
> | 大於 |
< | 小於 |
>= | 大於或等於 |
<= | 小於或等於 |
== | 等於 |
!= | 不等於 |
[userwin@MiWiFi-R3L-srv ~]$ df -h | grep "sda1" | awk '{print $5}' | awk 'BEGIN{FN="%"} $1>=20{print "磁盘使 用率超过20%"}' 磁盘使用率超过20% [userwin@MiWiFi-R3L-srv ~]$ df -h | grep "sda1" | awk '{print $5}' | awk 'BEGIN{FN="%"} $1>=80{print "磁盘使 用率超过80%"} $1<80{print "磁盘使用率未超过80%"}' 磁盘使用率未超过80%