
Linux三剑客之awk
awk简介
awk,全称GNU awk
此命令的设计者有 3 位,他们的姓分别是 Aho、Weingberger 和 Kernighan,awk 就取自这 3 为大师姓的首字母。
awk不仅仅是Linux中的一个命令,而且还是一种编程语言,可以用来处理和生成报告(excel)。它是Linux中最强大的文本处理工具,没有之一。
[root@m01 ~]#ls -l `which awk`lrwxrwxrwx. 1 root root 4 Sep 9 18:10 /usr/bin/awk -> gawk
一般我们使用awk,都是当做命令使用,所以我们称之为单行脚本那么awk能不能写脚本呢,必然可以,在linux系统中就有很多的awk脚本
[root@m01 ~]# find /usr/share/ -type f -name '*.awk'/usr/share/awk/assert.awk/usr/share/awk/bits2str.awk/usr/share/awk/cliff_rand.awk...
awk语法格式
# 语法格式awk [选项] '模式{动作1;动作2}' 文件有多个动作时;隔开# 选项-F 指定分隔符-v 传递命令行的变量 定义或修改一个awk内部的变量# 简单例子显示/etc/passwd行号,第一列,第三列和最后一列[root@m01 ~]# awk -F: '{print $1,$3,$NF}' /etc/passwd
awk的模式和动作
模式
[root@m01 ~]# cat /etc/passwdroot:x:0:0:root:/root:/bin/bashbin:x:1:1:bin:/bin:/sbin/nologin...[root@m01 ~]# awk -F: 'NR==1{print$1,$3}' /etc/passwd //先取第1行,再取列root 0比如上面这条命令'NR==1{print $1,$3}'对应就是'模式{动作}' 相当于:'条件{指令}'## 模式有:# 比较表达式NR==1NR>=10NR<=100NR>=1 && NR<=10$1>=100比如,取etc/passwd的1-3行[root@m01 ~]# awk 'NR<=3' /etc/passwd# 范围模式精确匹配行号:从第10行到第20行NR==10,NR==20[root@m01 ~]# awk 'NR==1,NR==3' /etc/passwd (效果同上)# 精确匹配字符串:从该字符串的行到另一个字符串所在行'/root/,/zls/''/从哪个字符串所在行/,/到那个字符串所在行/' #中间的行都包含进去比如:取出包含root的行,要讲要取的内容用//包含[root@m01 ~]# awk '/root/' /etc/passwdroot:x:0:0:root:/root:/bin/bashoperator:x:11:0:operator:/root:/sbin/nologin# 模糊匹配字符串:从含有该字符串所在行到含有另一字符串所在行'$1~/oo/,$1~/zl/'## 正则表达式模式# 正则表达式写法 也是用//包含'/正则表达式/flag' '$1~/正则表达式/flag''$1!~/正则表达式/flag'只不过我们在awk中很少使用flag## 特殊模式:BEGIN 和 END
动作
- print 打印
- gsub 替换
- gsub/被替换的内容/,"要替换的" ,$n指定要替换的列
- 变量赋值
- 统计计算
有多个动作时用;隔开
awk的常见变量

awk执行流程
- 读取文件前
- BEGIN{} - 读取文件之前,先判断命令的选项:-F,-v
- 如果写了BEGIN{},再执行BEGIN{}里面的动作 - 读取文件时
- {}
- awk读取文件时(和sed一样),一行一行读取文件
- 读取一行之后,判断是否满足条件'NR==3{print $0}',满足后再执行{}中的动作
- 如果不满足条件,awk继续读取下一行,直到满足条件或者到文件的最后一行
- 读取文件后
- END{}完成读取所有文件后,执行END{}里面的动作
任写哪个阶段都行,但END阶段不能单独使用
[root@m01 ~]# awk 'BEGIN{print 1+3}'4[root@m01 ~]# awk 'END{print 1+3}' 不行,后面要有文件名
注意:awk中单引号和双引号区别很大,双引号引字符串,单引号调用awk的变量
# 坑,在awk无法直接调用bash变量[root@m01 08:59:36 ~]# awk "/$HOSTNAME/{print $1}"
必须外面单引号里面双引号[root@m01 ~]# awk -F: 'BEGIN{print "用户名","UID"}{print $1,$3}END{print "文件读取完毕"}' /etc/passwd用户名 UIDroot 0bin 1daemon 2adm 3lp 4sync 5shutdown 6halt 7mail 8operator 11...[root@m01 ~]# awk -F: 'BEGIN{print "用户名","UID"}{print $1,$3}END{print "文件读取完毕"}' /etc/passwd|column -t用户名 UIDroot 0bin 1daemon 2adm 3lp 4sync 5shutdown 6halt 7mail 8operator 11games 12ftp 14nobody 99...