本站所有文章均为原创,如对您有帮助,恳请帮忙点击任何一处广告

Linux文本处理三剑客——awk命令使用教程

发布:TangLu2019-4-24 18:16分类: Linux命令 标签: awk grep

awk相对于grep的查找、sed的编辑来说,它更擅长对文本进行分析处理,awk和sed一样会把需要处理的文本按行读取到内存中,根据用户需要去灵活的处理文本并打印出来,也可以理解为过滤并处理文本


一、awk命令格式

awk -option 'BEGIN{}/pattern/{action}END{}' filename


下面将根据上面命令的格式进行拆分讲解:

1、option部分,用来指定额外选项

-F:在awk中默认的分隔符是空白符(包含空格和制表符),使用-F选项可以自定义分隔符,支持指定多个分隔符

cat /etc/passwd |awk -F':' '{print $1}' #指定分隔符为冒号
netstat -n | grep EST | awk -F '[ :]+' '{print $4}'  #利用正则表达式的+号将连在一起的同一个符号仅当做一个分隔符处理


awkjingjiang2.png

-f:从指定的配置文件中读取awk命令,示例:

awk -f awk.conf  test.txt


-v:使用该选项可以进行变量的定义,每一个“-v”定义一个变量

awk -v age=10 '{print age}'


2、action部分,用来指定需要做的具体操作

{action}部分是最关键的部分,用来指明需要做什么操作,默认为输出当前行(当前行可以用$0表示),也就是print,最常用的操作也就是print和printfprintf可以做格式化,比如左右对齐等),也可以增加自己需要打印出来的东西,这部分内容需要用引号,否则会被当做变量,下面是print格式化输出的例图

微信截图_20171030151955.png


再看下printf格式化输出后的结果,实现了对齐:

printf.png


printf格式化说明:
%s  字符类型
%d  数值类型
%f  浮点类型
-表示左对齐,默认是右对齐
printf不会自动换行,需要加\n


在进行print操作时可以使用AWK的位置变量,如print $1就是显示第一列的内容,也可以同时显示多列,如awk '{print $1,$2}',(当现实多列数据时,使用逗号会用空格作为默认分隔符,这里可以使用双引号自定义成其他字符作为分隔符,如'{ print $1"+"$2)}')。如图示例:

awkjingjiang3.png


3、pattern部分,用来做内容匹配,支持正则表达式

~:模糊匹配

awk -F: '$5~/root/{print $1} /etc/passwd'
awk  '/12:48:01/,/13:30:00/{print $0}'  /var/log/message #过滤出指定时间范围的日志


awk4.jpg

!~:与~相反,代表不匹配后面的内容

&&或者||:逻辑与或者逻辑或

cat /var/log/message | awk '$3=="linuxe" || $3 == "tanglu"'


==:完全精准匹配,非模糊匹配,看下面示例:用操作符做完全匹配,可以看到nologins虽然包含了nologin,但是最终结果并没有将其匹配出来

awk5.jpg

!=:将过滤结果进行反选后进行匹配
awk '$3!="linuxe"' /etc/passwd

>=:大于等于,当然也有<=、>、<等用于判断,示例:

awk -F: '$3>=1000{print $1,$3}' /etc/passwd


二、awk的内置变量

$0:整行内容

$1-$n:当前行的某个字段

FS:输入字段分隔符,默认为空白字符,作用和-F选项类似

awk -v FS=':' '{print $1}' /etc/passwd

OFS:输出字段分隔符,默认为空白字符
awk -v OFS=':'  '{print $2,$3}'/etc/passwd

RS、ORS:输入记录分隔符与输出记录分隔符,一行代表一个记录,所以可以理解为行分隔符


BEGIN{ }:在开始处理文本之前需要先执行一次且只执行一次的命令,示例:

awk -F: 'BEGIN{print "username      uid\n-----------------"}{print $1,$3}'  /etc/passwd 

END{ }:文本处理完成后需要执行一次的命令,用法同BEGIN{ },只不过是写在语句最后


NF:会记录awk命令所处理的每一行数据有几列字段。比如一行文字被分隔符为7列,那么{print NF}出的结果会显示成7。在awk中引用变量无需加$符号,如果是{print $NF},那么显示的结果就是具体第7列的值了,这个常用于直接显示每一行最后一个字段的值。还可以进行一些数学运算,{print $(NF-1)},结果就是倒数第二行

awk -F: '$NF=="/bin/bash"{print $1}' /etc/passwd


NR和FNR:打印出每一行的行号,不过在处理多个文件时有一点点区别,NR会直接把多个文件的行数依次显示出来,而FNR则对单个文件做行数的显示。看看示例:

awkvar2.jpg


NR通常用于取指定行内容,看看这个示例,取出2,3,4行的数据:

cat /etc/passwd | awk 'NR>1&&NF<5{print $0}'
cat /etc/passwd | awk 'NR==3{print $0}'


三、awk常用函数

# lentsh(str)  计算括号内字符串长度
# tolower(str)  将括号内字符串转换为小写
# toupper(str)  将括号内字符串转换为大写
# match(str,RE)  返回正则表达式匹配到的字符串的位置
# sub(RE,Repstr,str)  替换查找到的第一个字符串
# gsub(RE,Repstr,str)  替换查找到的所有字符串



四、awk扩展用法示例

1、awk的if判断,支持正则表达式

#可以遵循写法:{ if(){} else if(){} else if(){} else{} }
awk -F: '{if($3>=10) {print $1,$3}}' /etc/passwd
awk -F: '{if ($3~/^linuxe){print $0}}' /tmp/1.txt
awk -F: '{if($3==0){print $1,"the user is root"} else if($3>=500){print $1,"is common user"}}' /etc/passwd



2、awk数组与示例默认支持关联数组(关联数组的索引下标可以是单词而不局限于数字),通常用于统计(把想要统计的内容作为数组的索引)

#计算当前系统中普通用户和管理员的个数并显示出来,这里count和i都是定义的变量
awk  -F:  '{if($3==0){count++} else{i++}} END {print “管理员个数:”count ; print “普通用户数:”i}'  /etc/passwd

#使用awk进行计算,可用于统计某进程消耗资源。比如服务器Nginx启动了8个进程,那么该命令会将第一个进程消耗的CPU资源与后面依次相加,最后输出结果,当变量遇到与数值相加时默认是0,所以最后输出的结果就是1+2+3+4...=的结果了
ps aux |grep nginx |awk '{a=a+$3}END{print a}'

#统计访问日志中各个状态码的百分比
cat access.log | awk '{count[$9]++} END {for (status in count ){print status,count[status]/NR*100"%"}}'

#统计Apache或者Nginx某一天日志中不同IP访问量
grep '07/Aug/2018' access.log | awk '{ipcount[$1]++ } END{for(i in ipcount){print i,ipcount[i]} }' | sort -k2 -rn

#解析
#1、将日志每行的$1字段赋值给数组ipcount的索引,这里的$1是IP,所以这时数组内容是#ipcount[192.168.100.1]、ipcount[192.168.100.2]这样的
#2、索引的值根据处理的次数递增
#3、for循环遍历ipcount数组的索引并赋值给变量i,变量i的内容也就是ip了
#4、ipcount[i]就是ipcount这个数组的[i]索引的值,i已经定义为ip,所以最后得到的就是自增结束后的总值,实现了统计


#统计日志中访问量最高的页面
awk '/05\/Sep\/2018/{url[$7]++} END{for(i in url){print i,url[i]} }' access.log |sort -k2 -rn 


#统计TCP连接数。这里的$6是连接状态,比如LISTEN、ESTABLISHED等,把这个作为status变量的索引进行统计,然后最终输出
netstat -ntulp | grep 80 | awk '{status[$6]++} END {for (i in status){print i,status[i]} }'


温馨提示如有转载或引用以上内容之必要,敬请将本文链接作为出处标注,谢谢合作!
et_highlighter51
版权所有:《Linux运维技术学习站点
文章标题:《Linux文本处理三剑客——awk命令使用教程
除非注明,文章均为 《Linux运维技术学习站点》 原创
转载请注明本文短网址:http://www.linuxe.cn/post-139.html  [生成短网址]

已有 1/5231 人参与

评论:

御坂26169号 2016-08-01 09:38
老司机准备发车,biubiubiu

发表评论:

欢迎分享Linux运维技术学习站点

欢迎使用手机扫描访问本站,还可以关注微信哦~