awk 工作流程:
先执行BEGIN模块,再跟文本交互,最后执行END模块.也就是说BEGIN/END模块,这俩是单独操作跟文本是同一级,但执行有优先级,BEGIN模块>文本>END模块
行级处理器:跟文本交互是按行来的,读取一行内容,处理一行,然后重复这一流程,直到处理完.
程序结构:
开始块(BEGIN BLOCK)
规则(rule) = “匹配条件” + “处理动作” //非常类似iptables中处理数据包的规则
其中匹配条件含义:这行文本是否是这样的文本行.在iptables中含义,问数据包是否是这样的数据包.
结束块(END BLOCK)
awk基本用法
awk命令使用格式
awk ‘条件1{动作1}条件2{动作2}条件3{动作3 }’
也可以不加条件,不加条件表示每一行都处理
表示找到 df -h内容中 有dev/mapper/unikylin-root内容的 第五列的第一个字符
df -h |grep “dev/mapper/unikylin-root” |awk ‘{print $5}’|cut -d “%” -f 1
可以把上面这条语句输出的值赋给一个变量 并进行比较,比较后可以触发一些实际操作,比如说磁盘占满了就告警
[root@kylin236 ~ 14:12:23]# df -h
文件系统 容量 已用 可用 已用% 挂载点
/dev/mapper/unikylin-root 37G 8.6G 29G 24% /
devtmpfs 1.8G 0 1.8G 0% /dev
tmpfs 1.9G 8.0K 1.9G 1% /dev/shm
tmpfs 1.9G 89M 1.8G 5% /run
tmpfs 1.9G 0 1.9G 0% /sys/fs/cgroup
/dev/mapper/unikylin-opt 18G 16G 2.9G 85% /opt
/dev/sda1 1014M 250M 765M 25% /boot
tmpfs 371M 0 371M 0% /run/user/0
#对于 awk 命令来说,只要分隔开,不管是空格还是制表符,都可以识别
[root@kylin236 ~ 14:13:00]# df -h |grep "dev/mapper/unikylin-root" |awk '{print $5}'|cut -d "%" -f 1
24
[root@kylin236 ~ 14:13:09]# df -h |grep "dev/mapper/unikylin-root" |awk '{print $5}'
24%
printf命令行输出时是单引号 print ‘ %i\t %s\t %i\t %i\t %\t %8.2f\t \n’
在awk中用到print时,printf 要输出为双引号
awk ‘{printf $2 “\t” $6 “\n”}’ 1.txt
[root@kylin236 ~ 13:55:53]# cat 1.txt
ID Name PHP Linux MySQL Average
1 Liming 82 95 86 87.66
2 Sc 74 96 87 85.66
3 Gao 99 83 93 91.66
#输出第二列和第六列的内容
#这个例子中没有设定任何的条件类型,所以这个文件中的所有内容都符合条件,动作会无条件执行。
[root@kylin236 ~ 11:27:46]# awk '{printf $2 "\t" $6 "\n"}' 1.txt
Name Average
Liming 87.66
Sc 85.66
Gao 91.66
#使用print打印,会在每次输出后自动换行
[root@kylin236 ~ 16:07:23]# awk '{printf $2 "\t" $6 "\n"}' 1.txt
Name Average
Liming 87.66
Sc 85.66
Gao 91.66
#使用printf不带换行 \n 打印,printf只能识别标准输出格式,要加上 \n 才会换行
[root@kylin236 ~ 16:07:25]# awk '{printf $2 "\t" $6 }' 1.txt
Name AverageLiming 87.66Sc 85.66Gao 91.66
awk条件
awk支持的主要条件类型
条件类型 | 条 件 | 说 明 |
---|---|---|
awk保留字 | BEGIN | 在 awk 程序一开始,尚未读取任何数据之前执行。BEGIN 后的动作只在程序开始时执行一次 |
awk保留字 | END | 在 awk 程序处理完所有数据,即将结束时执行?END 后的动作只在程序结束时执行一次 |
关系运算符 | > | 大于 |
< | 小于 | |
>= | 大于等于 | |
<= | 小于等于 | |
== | 等于。用于判断两个值是否相等。如果是给变童赋值,则使用”=” | |
!= | 不等于 | |
A~B | 判断字符串 A 中是否包含能匹配 B 表达式的子字符串 | |
A!~B | 判断字符串 A 中是否不包含能匹配 B 表达式的子字符串 | |
正则表达式 | /正则/ | 如果在“//”中可以写入字符,则也可以支持正则表达式 |
BEGIN 的执行时机是”在 awk 程序一开始,尚未读取任何数据之前”。
当 awk 开始从文件中读入数据时,BEGIN 的条件就不再成立,所以 BEGIN 定义的动作只能被执行一次。
END 是在 awk 程序处理完所有数据,即将结束时执行的。END 后的动作只在程序结束时执行一次。
awk处理数据时是一行一行读取数据处理,最终打印出来的结果像是列。
// BEGIN
[root@kylin236 ~ 16:36:29]# awk 'BEGIN{printf "The Head \n"}{printf $2 "\t" $6 "\n"}' 1.txtThe Head
Name Average
Liming 87.66
Sc 85.66
Gao 91.66
// END
[root@kylin236 ~ 16:33:39]# awk 'END{printf "The End \n"}''{printf $2 "\t" $6 "\n"}' 1.txt
Name Average
Liming 87.66
Sc 85.66
Gao 91.66
The End
//大于,如果第六列大于87,就打印第二列的内容,同时不显示Name
//如果不大于,后面就不执行
cat 1.txt|grep -v Name|awk'$6>87{printf $2 "\n"}'
//识别字符串,在awk中识别字符串,需要用//包含
awk '/Liming/ {print}' 1.txt
//查看某列里是否包含某个字符串,
~表示包含的意思 A~B 判断字符串 A 中是否包含能匹配 B 表达式的子字符串
!~表示不包含 A!~B 判断字符串A中是否不包含能匹配B表达式的子字符串
awk '$2~ /Sc/ {printf $6 "\n"} 1.txt
awk内置变量
$0 $n
NF NR FS这个三个用的多,其他的都基本用不到
FS:用户自定义分隔符,awk默认分隔符是空格,也可以用tab,如果想要其他的分隔符,就要自定义
NF 当期全能拥有的字段和列的总数
NR当前awk所处理的行,是总数据的第几行
输出第一字段和第三字段 的行号NR值和 字段数值 NF
cat /etc/passwd |grep “bin/bash” |awk ‘BEGIN{FS=’:’} {printf $1 “\t” $3 “\t 行号:”NR “\t 字段数:”NF “\n”}
以 :为分隔符,提取第三列为500的用户
cat /etc/passwd |grep “bin/bash” |awk ‘BEGIN{FS=’:’} $3==”500” {print $1}’