awk命令不仅仅是Linux系统的命令,也是一种编程语言,用来处理数据和生成报告(Exel),处理的数据可以是一个或多个文件(标准输入和管道获取标准输入)。可在命令行上编辑操作,也可以写成awk程序运用。
awk格式
awk -F “参数” ‘BEGIN{} 模式 {动作} END{}’ 文件路径
参数
-F :指定按照什么标志进行文件的切割,切割成一列一列的,如何不指定-F参数,awk默认按照空格进行文本的切割。{}中的print代表输出的意思;
"$"代表取列,$1就是取第一列,以此类推
$NF:取每行的最后一列内容,默认取每行的最后一组元素
分隔符是 "(双引号) 条件是'(单引号)
BEGIN{}:告诉awk如何读取;END:告诉awk程序要如何结束
RS:读入换行符 ; ORS:输出换行符
:换行符
输出的以冒号为分割符的第一列
没加大括号就是模式,模式就是筛选数据的,有动作在执行动作,不写动作默认输出全部
基本的模式和动作
awk -F ":" 'NR>=2 &&NR<=6{print NR,$1}' /etc/passwd
命令说明:-F指定分隔符为冒号,相当于以“:”为菜刀,进行字段的切割。NR>=2 && NR<=6:这部分表示模式,是一个条件,表示取第2行到第6行。{print NR,$1}:这部分表示动作,表示要输出NR行号和$1第一列。
只有模式
awk -F ":" 'NR>=2&&NR<=6' /etc/passwd
命令说明:NR>=2&&NR<=6这部分是条件,表示第2行到第6行。但是这里没有动作,这里大家学要了解如果只有条件(模式)没有动作,awk默认输出整行
只有动作
awk -F ":" '{print NR,$1}' /etc/passwd
命令说明:这里没有模式,表示对每一行都处理,{print NR,$1}表示动作,显示NR行号与$1第一列,也就是没有模式的时候,awk会处理每一行
多个模式和动作
awk -F ":" 'NR==1{print NR,$1}NR==2{print NR,$NF}' /etc/passwd
命令说明:这里有多个条件与动作的组合 ,NR==1表示条件,行号(NR)等于1的条件满足的时候,执行{print NR,$1}动作,输出行号与第一列。NR==2表示条件,行号(NR)等于2的条件满足的时候,执行{print NR,$NF}动作,输出行号与最后一列
awk执行过程小结:
1 .awk读入第一行内容
2.判断是否符合模式中的条件NR>=2 ,a,如果匹配则执行对应的动作{print $0},b如果不匹配条件,继续读取下一行
3.继续读取下一行
4.重复过程1-3,直到读取最后一行
awk模式有四种:
正则表达式作为模式
比较表达式作为模式
范围模式
特殊模式BEGIN和END
正则表达式模式
显示第9列是200的行的IP地址
# awk ‘$9~/^200$/ {print $1}’ access.log
在第9列模式下,~进行正则匹配操作,以200开头,以200结尾过滤,
打印$1,显示IP地址
# awk ‘$9~/^404$/ {print $1}’ access.log | sort | uniq -c
在上述基础上,排序并去重、计数
或# awk ‘$9==”404” {print $1}’ access.log | sort | uniq -c
显示姓zhang的人的第二次捐款金额及他的名字
# awk -F “[ :]+” ‘$1~/^zhang/ {print $2,$(NF-1)}’ /server/files/reg.txt
显示xiaoyu的姓氏和ID号码
awk -F “[ : ]+” ‘$2~/^xiaoyu/ {print $1,3$}’ /server/files/reg.txt
显示所有以41开头的ID号码的人的全名和ID号码
awk -F “[ :]+” ‘$3~/~41/ {print $1,$2,$3}’ /server/files/reg.txt
显示所有以一个D或X开头的人名全名
awk -F “[: ]+” ‘$2~/^d|^x/ {print $1,$2}’ /server/files/reg.txt
显示所有ID号码最后一位数字是1或5的人的全名
awk -F “[ :]+” ‘$3~/1$|5$/ {print $1,$2}’ /server/files/reg.txt
显示xiaoyu的捐款,每个值都有以$开头,如$520$200$135
awk -F “[ :]+” ‘$2~/xiaoyu/ {print “$”$4”$”$5”$”$6}’ /server/files/reg.txt
显示所有人的全名,以姓、名的格式显示,如meng,feixue
awk -F “[ :]+” ‘{print $1”,”$2}’ /server/files/reg.txt
取网卡的IP地址
第一种
ifconfig eth0 | sed -n '2p' | awk -F "[ :]+" '{print $4}'
第二种
ifconfig eth0 | awk -F "[ :]+" 'NR==2{print $2}'
第三种
ifconfig eth0 | awk 'BEGIN{RS="[ :]}NR==31'
第四种
hostname -I
比较表达式模式
取出文件/etc/services的23-30行
awk ‘NR>=23&&NR<=30’ /etc/services
awk ‘NR>22&&NR<31’ /etc/services
判断某一列是否等于某个字符,找出/etc/passwd中第五列是root的行
awk -F":" '$5=="root"' /server/files/awk_equal.txt
awk -F":" '$5~/^root$/' /server/files/awk_equal.txt
找出工资在(40000,60000)之间的员工名字
awk -F: ‘$3>=”40000” && $3<=”60000” {print $1}’ test2
范围模式
显示第二行到第五行的行好和整行的内容
awk 'NR==2,NR==5{print NR,$0}' count.txt
显示以bin开头,到第五行的行号及整行内容
awk '/^bin/,NR==5{print NR,$0}' awkfile.txt
从第三列以bin开始的行到以lp开头的行并显示其行号和整行内容
awk -F":" '$5~/^bin/,/^lp/{print NR,$0}' awkfile.txt
从第三列以bin开头字符串的行到第三列以lp开头字符串的行
awk -F: '$5~/^bin/,$5~/^lp/{print NR,$0}' awkfile.txt
BEGIN模块
(1)定义内置变量(-F本质式修改的FS变量)
# ifconfig eth0|awk -F "(addr:)|( Bcast:)" 'NR==2{print $2}'
相当于# ifconfig eth0 | awk 'BEGIN{FS="(addr:)|( Bcast:)"} NR==2{print $2}'
# ifconfig eth0 | awk -F "[ :]+" 'NR==2{print $4}'
相当于# ifconfig eth0 | awk 'BEGIN{FS="[ :]+"}NR==2{print $4}'
# ifconfig eth0 | awk -F "[^0-9.]+" 'NR==2{print $2}'
相当于# ifconfig eth0 | awk 'BEGIN{FS="[^0-9.]+"}NR==2{print $2}'
(2)在读取文件之前,输出提示性信息(表头)
# awk -F ":" 'BEGIN{print "1111","2222"} {print $1,$3} ' yunjisuan.txt
# awk -F ":" 'BEGIN{print "1111","2222"} {print $1,$3} END{print "asdf","asdfg"}' yunjisuan.txt
(3)使用BEGIN 模块的特殊性质,进行一些测试(计算)
计算数值
# awk 'BEGIN{print 10/3}'
赋值变量
# awk 'BEGIN{a=1;b=2;print a,b,a+b}'
awk中字母会被认为是变量,给一个变量赋值字母(字符串),用双引号
# awk 'BEGIN{abcd=123456;a=abcd;print a}'
123456
# awk 'BEGIN{a="abcd";print a}'
abcd
表示a的b次方
# awk ‘BEGIN{a=2;b=3;print a**b}’
查看/etc/services空行个数
方法一:
# grep -c “^$” /etc/services
方法二:
# awk ‘/^$/ {i=i+1} END{print i}’ /etc/services
其中,i=i+1 等同于i++
查看test文件一共有多少行
# awk ‘{i++}END{print i}’ test
求test文件每行的值之和
# awk ‘{i=i+$0}END{print i}’ test
求 test文件每行的值之积(BEGIN初始变量设定位置)
# awk ‘BEGIN{i=1}{i=i*$1}END{print i}’ test