GNU awk
报告生成器,格式化文本输出;
AWK:Aho,Weinberger,Kernighan --> new AWK,NAWK
GUN awk,gawk
[root@localhost tmp]# ls -l /usr/bin/awk
lrwxrwxrwx. 1 root root 4 6月 5 12:53 /usr/bin/awk -> gawk
基本用法;gawk [options] 'program' file...
program:PATTERN{action statements}
语句之间用分号分隔
print printf
选项:
-F:指明输入时用到的字段分隔符;
-v var=value;自定义变量
tail -3 /etc/fstab | awk '{print $2,$4}'
1.print
要点:逗号分隔符;
输出的个item可以字符串,也可以是数值;当前记录的字段,变量或者awk的表达式
tail -3 /etc/fstab | awk '{print "hello",$2,$4}'
2.变量
内建变量
FS:input field seperator,默认为空白字符;
OFS:output field seperator,默认为空白字符;
awk -v FS=':' -v OFS=':' '{print $1,$3,$7}' /etc/passwd
-v FS 指定输入分隔符
-v OFS 指定输出分隔符
RS:input record seperator,输入时的换行符;
awk -v RS=' ' '{print}' /etc/passwd
ORS:output record seperator,输出时的换行符
NF;number of field,字段数量
统计每一行的字段数
awk '{print NF}' /etc/fstab
显示最后一个字段
awk '{print $NF}' /etc/fstab
NR;number of record 行数
awk '{print NR}' /etc/fstab
FNR:各文件分别计数
awk ‘{print FNR}’ /etc/fstab /etc/issue
FILENAME:文件名
ARGC:命令行参数的个数
ARGV:数组,保存的是命令行所给定的各参数;
自定义变量
(1)-v var=value
变量名区分字符大小写;
awk -v test='hello gawk' 'BEGIN{print test}'
(2)在program中直接定义
awk 'BEGIN{test="hello gawk";print test}'
3.printf命令
格式化输出:prinf FORMAT,item1,item2,。。。。
1.FORMAT必须给出;
2.不会自动换行,需要显示给出换行控制符,\n
3.FORMAT中需要分别为后面的每个item指定一个格式化符号;
格式符
%c:显示字符的ASCII码
%d,%i;显示十进制整数;
%e,%E;科学计数法数值显示
%f:显示为浮点数
%g,%G;以科学计数法或浮点形式显示数值
%s;显示字符串
%u:无符号整数
%%:显示%自身
awk -F: '{printf "Username: %s,Uid: %d\n",$1,$3}' /etc/passwd
修饰符:
#[.#]:第一个数字控制显示的宽度;第二个#表示小数点后的精度
%3.1f
-:左对齐显示
+: 显示数值的符号
awk -F: '{printf "Username: %-15s Uid: %d\n",$1,$3}' /etc/passwd
4.操作符
算术操作符;
x+y,x-y,x*y,x/y,x^y,x%y
-x
+x:转换为数值
字符串操作符;没有符号的操作符,字符串连接
赋值操作符;
=,+=,-=,*=,/=,%=,^=
++,--
比较操作符;
>,>=,<,<=,!=,==
模式匹配符;
~:是否匹配
!~:是否不匹配
逻辑操作符;
&&
||
!
函数调用:
function_name(argu1,argu2,...)
条件表达式;
selector?if-true-expression-false-expression
awk -F: '{$3>=1000?usertype="Common User":usertype="sysadminor SysUser";printf "%15s:%-s\n",$1,usertype}' /etc/passwd
5.PATTERN
1.empty:空模式,匹配每一行
2./regular expression/:仅处理能够被模式匹配到的行
awk '/^UUID/{print $1}' /etc/fstab
3.relational expression;关系表达式,结果为真才会被处理;
真:结果为非0值,非空字符串;
id号大于等于1000的用户
awk -F: '$3>=1000{print $1,$3}' /etc/passwd
默认shell是bash的用户
awk -F: '$NF=="/bin/bash"{print $1,$3}' /etc/passwd
awk -F: '$NF~/bash/{print $1,$3}' /etc/passwd
4.line ranges:行范围;
awk -F: '10,20{print $1}' /etc/passwd
awk -F: '/^h/,/^u/{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}
if(condition){statements}else {statements}
while(condition){statements}
do{statements}while(condition)
for(expr1;expr2;expr3;){statements}
break
continue
delete arry[index]
delete arry
exit
{statements}
7.1 if-else
语法:if(condition)statement [else statement]
判断用户ID是否大于1000
awk -F: '{if($3>=1000) {printf "common user: %s\n",$1} else {printf "root or sysuser: %s\n",$1}}' /etc/passwd
判断默认为bin/bash
awk -F: '{if($NF=="/bin/bash") print $1}' /etc/passwd
判断字段数
awk '{if(NF>5) print $0}' /etc/fstab
判断磁盘使用量
df -h | awk -F% ' /^\/dev/{print $1}' | awk '{if($NF>=10) print $1}'
7.2 while循环
语法:while(condition) statement
判断文件中中每个字段长度
awk '/^[[:space:]]*linux16/{i=1;while(i<=NF) {if (length($1)>=7) {print $i,length($i); i++}}' /etc/grub2.cfg
判断文件中的每个字段长度只输出长度大于等于7的字段
awk '/^[[:space:]]*linux16/{i=1;while(i<=NF) {if (length($1)>=7) {print $i,length($i)}; i++}}' /etc/grub2.cfg
7.3 do while循环
语法:do statement while(condition)
意义:至少执行一次循环体
7.4 for循环
语法:for(expr1;expr2;expr3) statement
for(i=1;i<=100;i++)
7.5 switch语句
语法:swith(expression) {case value or /REGEXP/: statement;case value or /REGEXP2/: statement;....;default: statement}
7.6 break和continue
break[n]
continue
7.7 next
提前结束对本行的处理,直接进入下一行;
awk -F: '{if($3%2!=0) next; print $1,$3}' /etc/passwd
8.arry
关联数组:array[index-expression]
index-expression
1.可以使用任意字符串:字符串要使用双引号
2.如果某数组元素事先不存在,在引用时,AWK会自动创建此元素,并将其值初始化为空串
若要判断数组中是否存在某个元素,要使用“index in array”格式进行
判断LIS和EST出现的次数
netstat -tan | awk '/^tcp\>/{state[$NF]
++}END{for (i in state){print i,state[i]}}'
统计/etc/fstab,文件中每个单词出现的次数;
awk '{for(i=1;i<=NF;i++){count[$i]++}}END{for (i in count) {print i ,count[i]}}' /etc/fstab
9.函数
9.1内置函数
数值处理:rand():返回0和1之间的一个随机数。
awk 'BEGIN{print rand()}'
字符串处理:length():返回指定字符串的长度;
sub(r,s,[t]):将第一次出现的r替换为s。
split(s,a[,r]);以r为分隔符切割s,并将结果保存在a所表示的数组中。
9.2自定义函数
本文转自阿伦艾弗森 51CTO博客,原文链接:http://blog.51cto.com/perper/1956221,如需转载请自行联系原作者