首页 > 代码库 > gawk 文本处理入门用法详集
gawk 文本处理入门用法详集
gawk - pattern scanning and processing language
报告生成器,可进行格式化输出,文本处理三剑客之一,是基于sed和grep功能的扩展
一般用法格式:
awk [options] ‘program‘ FILE... program: /regular/{print}
语句之间用分号分隔
print,printf
选项:
-F:指明输入时用到的字段
-v var=value:指明自定变量
awk运作方式:
逐行读入文本,并将每个字段给予一个变量进行存储,$1..$NF ,而$0标识一整行
显示文本的的2,4字段,默认是空格为分隔符,默认输出以空格为分隔符
tail -3 /etc/fstab | awk ‘{print $2,$4}‘
1.print item1,item2...
以逗号作为分隔符 变量的引用,不允许在""内部 省略item,则默认print $0
2.变量
1.内键变量
FS:input field seperator指明输入字段分隔符类似-F
OFS:output field seprator 指明输出字段分隔符
RS:input record seperator输入时的换行符
]# awk -v RS=‘ ‘ ‘{print}‘ /etc/passwd
ORS:output record seperator输出时的换行符
NF:number of field,每行的字段数量
$NF:最后一个字段
NR:number of record,行数
FNR:各文件分别计数
FILENAME:当前的文件名
ARGC:命令行参数的个数(program 不为参数)
]# awk ‘BEGIN{print ARGC}‘ /etc/fstab
ARGV:数组,保存,命令行中所给定的每个字段
2.自定义变量
-v var=value
变量名区分大小写
]# awk -v test=‘hello gawk‘ ‘BEGIN{print test}
在program中直接定义
]# awk ‘BEGIN{test="hello gawk";print test}‘
3.printf命令:格式化输出
printf "FORMAT1,FORMAT2",item1,item2... ===>FORMAT与item对应位置的格式化 1.FORMAT是必须要给出 2.printf不自动换行,显式给出换行符\n 2.FORMAT需要分别为后面的每个item指定一个格式化符号
格式符(需用双引号):
%c :显示字符的ASCII码 %d %i:显示十进制整数 %e %E:科学计数法数值显示 %f:显示浮点数 %g,%G:以科学计数法或浮点数显示数值 %s:显示字符串 %u:无符号整数 %%:显示%自身
格式化输出示例:
]# awk -F: ‘{printf "Username: %s\n",$1}‘ /etc/passwd
修饰符:加在格式符之前,用于控制格式符的显示方式
#.# 第一个数字控制显示宽度;第二个#表示小数点后的精度
%3.2f - : 显示为左对齐 + : 显示数值的符号,有正数负数之分
示例:
]# awk -v FS=‘:‘ ‘{printf "username: %-25s,UDI: %-25d\n",$1,$3}‘ /etc/passwd
4.操作符
算术操作符
x+y,x-y,x*y,x^y,x/y,x%y -x:正数转化为负数 +x:字符串转化为数值
字符串操作符:没有符号的操作符,字符串的连接
赋值操作符: =,+=,-=,*=,/=,%=,^= ++,-- 比较操作符: >,<,>=,<=,!=,== 模式匹配符: ~:是否匹配 !~:是否不匹配 逻辑操作符: && || !
函数调用:
function_name(argu1,argu2,...) 条件表达式:(三目运算) selctor?if-true-expression:if-false-expression
示例:查找本机的普通用户及系统用户
# awk -F: -v OFS=":" ‘{$3>1000?usertype="common user":usertype="system user";printf "%-18s,%s\n",$1,usertype}‘ /etc/passwd
5.PATTERN
1 .empty:空模式,匹配每一行
2 ./regular expression/:文本过滤仅处理被模式匹配到的行
]# awk ‘/^UUID/{print $1}‘ /etc/fstab
3 .relatinal expression:关系表达式:结果为真式,才会被处理;非零为真
]# awk -F: ‘$3>=1000{print $1,$3}‘ /etc/passwd
查找其用户的默认shell为/bin/bash的用户
]# awk -F: ‘$NF=="/bin/bash"{print $1,$NF}‘ /etc/passwd ]# awk -F: ‘$NF~/bash$/{print $1,$NF}‘ /etc/passwd
4 .lines ranges:行范围
startline,endline
注意:不支持直接指定数字,可以容如下方式
]# awk -F: ‘(NR>=2&&NR<=5){print $1,$2}‘ /etc/passwd /part1/,/part2/ ]# awk -F: ‘/^h/,/^9/{print $1}‘ /etc/passwd
5 .BEGIN/END模式:处理开始之前处理一次
BEGIN{}:仅在开始处理文件中的文件之前执行一次:
END{}:仅在文本处理完成之后执行一次
]# awk -F: ‘BEGIN{print "username uid \n----------"}{print $1,$3‘ /etc/passwd
6 .常用的action:
1.expressions 2.control statements:if ,while,等; 3.compound statements:组合语句; 4.input statements 5.output statements
7 .控制语句
if(condition) {statements} else {statments} while(condition) {statements} for(expr1;expr2;expr3) {statements} {statements}组合语句需要{}
if-else
语法: if(condition) statements [else statements]
]# awk -F: ‘{if($3>=1000) {printf "common user:%s\n",$1} else {printf "system user: %s\n ",$1}}‘ /etc/passwd
取得磁盘利用率:
]# df -h| awk -F [%] ‘/^\/dev/{print $1}‘|awk ‘{if($NF>=10) print $1}‘
while循环:
语法:while(condition) statements
条件为"真",进入循环;条件为假则退出循环
使用场景:对一行内的多个字段逐一处理,对数组中的字段做逐一处理函数:length()字符长度
统计每个字段的长度?
~]# awk ‘/[[:space:]]*linux16/{i=1;while(i<=NF) {print $i,length($i);i++}}‘ /etc/grub2.cfg
并统计出大于7的字段?
~]# awk ‘/[[:space:]]*linux16/{i=1;while(i<=NF) {if(length($i)>=7) {print $i,length($i)};i++}}‘ /etc/grub2.cfg
do-while循环
语法:do statement while(condition) 意义:先执行循环语句,而后在判断执行while循环
for循环:
语法:for(expr1;expr2;expr3) statement
for(variable assignment;condition;iteration proccess) {for-body}~]# awk ‘/[[:space:]]*linux16/{for(i=1;i<=NF;i++) {print $i,length($i)}}‘ /etc/grub2.cfg
特殊用法:
能够遍历数组中的元素:for(var in array) {for-body}
switch语句:
语法: switch(expression) {case VALUE1 or /REGEXP/:statement;case VALUE2 or /REGEXP/:statement...;default statement}
break和continue
break [n] :跳出n层循环
next
提前结束对本行的处理而直接进入下一行 仅显示偶数的uid用户? ~]# awk -F: ‘{if($3%2!=0) next; print $1,$3}‘ /etc/passwd
array
关联数组:array[index-expression]index-expression: 1.可使用任意字符串;索引要使用双引号"";array["mon"]=Monday 2.如果某元素事先不存在,在引用时awk会自动将此元素创建并将其赋值为空串
若要判断数组中是否存在某元素,要使用"index in array"格式进行
若要遍历数组中的每个元素,要使用for循环:
for(var in array) {for-body}
~]# awk ‘BEGIN{weekdays["mon"]="monday";weekdays["tue"]="tuesday";for(i in weekdays) {print weekdays[i]}}‘ 注意:var会遍历array的每个索引;
查看netstat -nat中tcp状态出现的次数?
~]# netstat -tan |awk ‘/^tcp\>/{state[$NF]++}END{for(i in state) {print i,state[i]}}‘
查看ss -nat中tcp状态出现的次数?
~]# ss -tan |awk ‘{state[$1]++}END{for(i in state) {print i,state[i]}}‘
查看ip地址的访问量?
~]# awk ‘{ip[$1]++}END{for(i in ip) {print i,ip[i]}}‘ /var/log/httpd/access_log
统计/etc/fstab中文件系统的个数?
~]# awk ‘/^UUID/{fs[$3]++}END{for(i in fs) {print i,fs[i]}}‘ /etc/fstab
统计指定文件中每个单词出现的次数?
~]# awk ‘{for(i=1;i<=NF;i++) {count[$i]++}}END{for(i in count) {print i,count[i]}}‘ /etc/fstab
9.内置函数:
数值处理: rand():返回指定字符串的长度; 字符处理: length([s]):返回指定字符串的长度; sub(r,s,[t]):以r表示模式查找t所表示的字符中匹配的内容,并将其第一次出现替换为s所表示的内容; gsub(r,s,[t]):以r表示模式查找t所表示的字符中匹配的内容,并将全局出现替换为s所表示的内容; splits(s,a[,r]):以r为分隔符切割字符s,并将切割后的结果保存至a所代表的的数组中
统计ip地址出现的次数?
~]# netstat -tan|awk ‘/^tcp\>/{split($5,ip,":");count[ip[1]]++}END{for(i in count) {print i,count[i]}}
本文出自 “老城小叙” 博客,请务必保留此出处http://cityx.blog.51cto.com/9857477/1927819
gawk 文本处理入门用法详集