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
可以把上面这条语句输出的值赋给一个变量 并进行比较,比较后可以触发一些实际操作,比如说磁盘占满了就告警

  1. [root@kylin236 ~ 14:12:23]# df -h
  2. 文件系统 容量 已用 可用 已用% 挂载点
  3. /dev/mapper/unikylin-root 37G 8.6G 29G 24% /
  4. devtmpfs 1.8G 0 1.8G 0% /dev
  5. tmpfs 1.9G 8.0K 1.9G 1% /dev/shm
  6. tmpfs 1.9G 89M 1.8G 5% /run
  7. tmpfs 1.9G 0 1.9G 0% /sys/fs/cgroup
  8. /dev/mapper/unikylin-opt 18G 16G 2.9G 85% /opt
  9. /dev/sda1 1014M 250M 765M 25% /boot
  10. tmpfs 371M 0 371M 0% /run/user/0
  11. #对于 awk 命令来说,只要分隔开,不管是空格还是制表符,都可以识别
  12. [root@kylin236 ~ 14:13:00]# df -h |grep "dev/mapper/unikylin-root" |awk '{print $5}'|cut -d "%" -f 1
  13. 24
  14. [root@kylin236 ~ 14:13:09]# df -h |grep "dev/mapper/unikylin-root" |awk '{print $5}'
  15. 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

  1. [root@kylin236 ~ 13:55:53]# cat 1.txt
  2. ID Name PHP Linux MySQL Average
  3. 1 Liming 82 95 86 87.66
  4. 2 Sc 74 96 87 85.66
  5. 3 Gao 99 83 93 91.66
  6. #输出第二列和第六列的内容
  7. #这个例子中没有设定任何的条件类型,所以这个文件中的所有内容都符合条件,动作会无条件执行。
  8. [root@kylin236 ~ 11:27:46]# awk '{printf $2 "\t" $6 "\n"}' 1.txt
  9. Name Average
  10. Liming 87.66
  11. Sc 85.66
  12. Gao 91.66
  13. #使用print打印,会在每次输出后自动换行
  14. [root@kylin236 ~ 16:07:23]# awk '{printf $2 "\t" $6 "\n"}' 1.txt
  15. Name Average
  16. Liming 87.66
  17. Sc 85.66
  18. Gao 91.66
  19. #使用printf不带换行 \n 打印,printf只能识别标准输出格式,要加上 \n 才会换行
  20. [root@kylin236 ~ 16:07:25]# awk '{printf $2 "\t" $6 }' 1.txt
  21. 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处理数据时是一行一行读取数据处理,最终打印出来的结果像是列。

  1. // BEGIN
  2. [root@kylin236 ~ 16:36:29]# awk 'BEGIN{printf "The Head \n"}{printf $2 "\t" $6 "\n"}' 1.txtThe Head
  3. Name Average
  4. Liming 87.66
  5. Sc 85.66
  6. Gao 91.66
  7. // END
  8. [root@kylin236 ~ 16:33:39]# awk 'END{printf "The End \n"}''{printf $2 "\t" $6 "\n"}' 1.txt
  9. Name Average
  10. Liming 87.66
  11. Sc 85.66
  12. Gao 91.66
  13. The End
  14. //大于,如果第六列大于87,就打印第二列的内容,同时不显示Name
  15. //如果不大于,后面就不执行
  16. cat 1.txt|grep -v Name|awk'$6>87{printf $2 "\n"}'
  17. //识别字符串,在awk中识别字符串,需要用//包含
  18. awk '/Liming/ {print}' 1.txt
  19. //查看某列里是否包含某个字符串,
  20. ~表示包含的意思 A~B 判断字符串 A 中是否包含能匹配 B 表达式的子字符串
  21. !~表示不包含 A!~B 判断字符串A中是否不包含能匹配B表达式的子字符串
  22. 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}’

https://www.cnblogs.com/pangbing/p/6918202.html