awk 命令使用
截取符合条件的列
awk 先读取第一行后,再去处理数据
例子:
cut 不能截取分隔符为空格,tab之类的文件或字符串,但awk可以
[root@zabbix lianxi]# df -h
文件系统 容量 已用 可用 已用% 挂载点
/dev/mapper/centos-root 17G 1.5G 16G 9% /
devtmpfs 1.9G 0 1.9G 0% /dev
tmpfs 1.9G 0 1.9G 0% /dev/shm
tmpfs 1.9G 12M 1.9G 1% /run
tmpfs 1.9G 0 1.9G 0% /sys/fs/cgroup
/dev/sda1 1014M 189M 826M 19% /boot
tmpfs 378M 0 378M 0% /run/user/0
[root@zabbix lianxi]# df -h | cut -d " " -f 5
[root@zabbix lianxi]#
[root@zabbix lianxi]# awk '{printf $2 "\t" $6}' student.txt
Name AverageLiming 87.66Sc 85.66Gao 91.66[root@zabbix lianxi]# awk '{printf $2 "\t" $6\n}' student.txt
awk: cmd. line:1: {printf $2 "\t" $6\n}
awk: cmd. line:1: ^ backslash not last character on line
awk: cmd. line:1: {printf $2 "\t" $6\n}
awk: cmd. line:1: ^ syntax error
[root@zabbix lianxi]# awk '{printf $2 "\t" $6 "\n"}' student.txt
Name Average
Liming 87.66
Sc 85.66
Gao 91.66
##############################################################################
解释:$2 $6 代表文件的第2列和第6列,awk先读取文件的一行,并判断条件提取符合条件的信息,再读取下一行提取
$0 代表整行
[root@zabbix lianxi]# df -h
文件系统 容量 已用 可用 已用% 挂载点
/dev/mapper/centos-root 17G 1.5G 16G 9% /
devtmpfs 1.9G 0 1.9G 0% /dev
tmpfs 1.9G 0 1.9G 0% /dev/shm
tmpfs 1.9G 12M 1.9G 1% /run
tmpfs 1.9G 0 1.9G 0% /sys/fs/cgroup
/dev/sda1 1014M 189M 826M 19% /boot
tmpfs 378M 0 378M 0% /run/user/0
[root@zabbix lianxi]# df -h | awk '{printf $6 "\t" $2 "\n"}'
挂载点 容量
/ 17G
/dev 1.9G
/dev/shm 1.9G
/run 1.9G
/sys/fs/cgroup 1.9G
/boot 1014M
/run/user/0 378M
[root@zabbix lianxi]# df -h | awk '{print $6 "\t" $2}'
挂载点 容量
/ 17G
/dev 1.9G
/dev/shm 1.9G
/run 1.9G
/sys/fs/cgroup 1.9G
/boot 1014M
/run/user/0 378M
############################################
print与printf的区别
print 默认行尾自动添加换行符,printf需要手动添加
[root@zabbix lianxi]# df -h | grep sda1
/dev/sda1 1014M 189M 826M 19% /boot
[root@zabbix lianxi]# df -h | grep sda1 | awk '{print $5}' | cut -d "%" -f 1
19
##################################
BEGIN
[root@zabbix lianxi]# awk 'BEGIN {print "这是一个测试脚本"} {print $2 "\t" $6}' student.txt
这是一个测试脚本
Name Average
Liming 87.66
Sc 85.66
Gao 91.66
解释:只有满足了条件才能执行后面,也就是说先执行BEGIN语句后,再处理后面的数据。
############################################
FS 内置变量
作用:指定分隔符
[root@zabbix lianxi]# awk '{FS=":"} {print $1 "\t" $3}' /etc/passwd
root:x:0:0:root:/root:/bin/bash
bin 1
daemon 2
adm 3
lp 4
sync 5
shutdown 6
halt 7
mail 8
operator 11
games 12
ftp 14
nobody 99
systemd-network 192
dbus 81
polkitd 999
sshd 74
postfix 89
chrony 998
apache 48
zabbix 997
mysql 27
user1 1000
user2 1001
user3 1002
为什么第一行没有过滤?
因为:awk 先读取第一行后,再去处理数据
解决办法:再分隔符前添加BEGIN,这样先执行分隔符后,再读取第一行,并执行数据处理
注意:手工添加分隔符必须添加BEGIN
[root@zabbix lianxi]# awk 'BEGIN {FS=":"} {print $1 "\t" $3}' /etc/passwd
root 0
bin 1
daemon 2
adm 3
lp 4
sync 5
shutdown 6
halt 7
mail 8
operator 11
games 12
ftp 14
nobody 99
systemd-network 192
dbus 81
polkitd 999
sshd 74
postfix 89
chrony 998
apache 48
zabbix 997
mysql 27
user1 1000
user2 1001
user3 1002
[root@zabbix lianxi]#
[root@zabbix lianxi]# awk 'BEGIN {FS=":"} {print $1 "\t" $3} END {print "aaaaaaaaa"}' /etc/passwd
root 0
bin 1
daemon 2
adm 3
lp 4
sync 5
shutdown 6
halt 7
mail 8
operator 11
games 12
ftp 14
nobody 99
systemd-network 192
dbus 81
polkitd 999
sshd 74
postfix 89
chrony 998
apache 48
zabbix 997
mysql 27
user1 1000
user2 1001
user3 1002
aaaaaaaaa
[root@zabbix lianxi]# awk 'BEGIN {print "开始执行"} BEGIN {FS=":"} {print $1 "\t" $3} END {print "结束了"}' /etc/passwd
开始执行
root 0
bin 1
daemon 2
adm 3
lp 4
sync 5
shutdown 6
halt 7
mail 8
operator 11
games 12
ftp 14
nobody 99
systemd-network 192
dbus 81
polkitd 999
sshd 74
postfix 89
chrony 998
apache 48
zabbix 997
mysql 27
user1 1000
user2 1001
user3 1002
结束了
###################################################################
关系运算符
[root@zabbix lianxi]# cat student.txt | grep -v Name
1 Liming 82 95 86 87.66
2 Sc 74 96 87 85.66
3 Gao 99 83 93 91.66
[root@zabbix lianxi]# cat student.txt | grep -v Name | awk '$6 >=86 {print $2}'
Liming
Gao
解释:查看student.txt 文件,取出不含Name的行,如果第6列的数据大于等于86,则打印第2列数据