基础概念

报告生成器,将文本信息以指定方式格式化以后显示
awk指令是由模式,动作,或者模式和动作的组合组成。模式既pattern,可以类似理解成sed的模式匹配,可以由表达式组成,也可以是两个正斜杠之间的正则表达式。比如NR==1,这就是模式,可以把他理解为一个条件。
动作即action,是由在大括号里面的一条或多条语句组成,语句之间使用分号隔开。

image.png

1 print

使用格式:
print item1,item2,…
要点:
1.各项目之间使用都好隔开,而输出时则以空白符分隔;
2.输出的item可以为字符串或者数值,当前记录的字段(如$1),变量或awk的表达式;数值会先转换为字符串,而后再输出
3.print命令后面的item可以省略,此时其功能相当于print $0,因此,如果想输出空白行,则需要使用print “”;
例子:
# awk ‘BEGIN { print “line one\nline two\nline three”}’
image.png
# awk -F: ‘{print $1,$3}’ /etc/passwd
image.png

2 awk变量

2.1 记录变量

FS:field separator,读取文本时,所使用字段分隔符
RS:Record separator,输入文本信息所使用的换行符
OFS:Output Field Separator
ORS:Output Row Separator

2.2 awk内置变量之数据变量

NR:awk命令所处理的记录数,如果有多个文件,这个数目会把处理的多个文件中行统一计数
NF:当前记录的filed个数(处理当前行的字段个数)
FNR:与NR不同的是,FNR用于记录正在处理的行是当前这一个文件中被总共处理的行数
ARGV:数组,保存命令本身这个字符串,如awk ‘{print $0}’ a.txt b.txt 这个命令中,ARGV[0]保存awk,ARGV[1]保存a.txt
ARGC:awk命令的参数个数
FILENAME:awk命令所处理的文件的名称
ENVIRON:当前shell环境变量及其值得关联数组
如 awk ‘BEGIN{print ENVIRON[“PATH”]}’

2.3 用户自定义变量

awk允许用户自定义自己的变量以便于再程序代码中使用,
[root@web01 ~]# awk ‘BEGIN{var=”xiang”;print var}’
xiang
[root@web01 ~]# awk -v var=”variable testing” ‘BEGIN{print var}’
variable testing

3 printf

printf命令的使用格式
printf format,item1, item2,…
要点:
1.其与print命令的最大不同是,printf需要指定format
2.format用于指定后面的每个item的输出格式
3.printf语句不会自动打印换行符:\n
format格式的指示符都以%开头,后跟一个字符,如下:
%c:显示字符的ASCII码
%d,%i:十进制整数
%e,%E:科学计数法显示数值
%f:显示浮点数
%g,%G:以科学技术法的格式或浮点数的格式显示数值
%s:显示字符数
%u:无符号整数
%%:显示%自身
修饰符:
N:显示宽度
-:左对齐
+:显示数值符号
例子:
[root@web01 ~]# awk -F: ‘{printf “%-15s %i\n”,$1,$3}’ /etc/passwd
root 0
bin 1
daemon 2

4 awk的算术操作符

-x:负值
+x:转换为数值
x^y:
x*y:次方
x
y:乘法
x/y: 除法
x+y:
x-y:
x%y:
布尔值
x ~ y x为一个
x !~y
三目运算
selector? if-true-exp:if-false-exp
如:
a=3 b=4
a>b ? a is max:b is max

5 常见模式类型

1.Regexp:正则表达式,格式为/regular expression/
2.expression:表达式,其值非0或为非空字符时满足条件,如$1 ~ /foo/ 或$1 ==”magedu”, 用运算符~(匹配)和~!(不匹配)
3.Ranges:指定的匹配范围,格式为pat1,pat2
4.BEGIN/END:特殊模式,仅在awk命令执行前运行一次或结束前运行一次
5.Empty:空模式,匹配任意字符行
/正则表达式/:使用通配符扩展集,
关系表达式:可以用下面运算符表中的关系运算符进行操作,可以是字符串或数字的比较,如$2>%1选择第二个字段比第一个字段长的行
模式匹配表达式:
模式:执行行的范围,该语法不能包括BEGIN和END模式
BEGIN:让用户指定在第一条输入记录被处理之前所发生的动作,通常可以在这里设置全局变量
END:让用户在最后一条输入记录被读取之后发生的动作
1.Regexp:正则表达式
显示以r开头的行中第一个字符串
[root@web01 ~]# awk -F: ‘/^r/{print $1}’ /etc/passwd
root
rpc
rpcuser
2.expression:表达式
可以是比较表达式,布尔表达式
如,显示用户id号大于1000的用户
[root@web01 ~]# awk -F: ‘$3>1000{print $1,$3}’ /etc/passwd
nfsnobody 65534
www 1001
如取出shell为bash的用户
[root@web01 ~]# awk -F: ‘$7~”bash$”{print $1,$7}’ /etc/passwd
root /bin/bash
xiang /bin/bash
3.Ranges:指定的匹配范围
如显示以r开头的行到a开头的行中指定字符串
[root@web01 ~]# awk -F: ‘/^root/,/^a/{print $1,$7}’ /etc/passwd
root /bin/bash
bin /sbin/nologin
daemon /sbin/nologin
adm /sbin/nologin
4.BEGIN/END:特殊模式
例子:命令执行之前显示Username ID Shell,并以指定的格式显示以root开头的行到以daemon开头行指定字符穿内容,并在命令结束前显示END of report.
[root@web01 ~]# awk -F: ‘BEGIN{print “Username ID Shell”}/^root/,/^daemon/{printf “%-10s%-10s%-20s\n”,$1,$3,$7}END{print “END of report.”}’ /etc/passwd
Username ID Shell
root 0 /bin/bash
bin 1 /sbin/nologin
daemon 2 /sbin/nologin
END of report.
image.png
5.Empty:空模式

6 常见的action

1.Expression
2.Control statements
3.Compund statements
4.Inout statements
5.Output statements
1.Expression
2.Control statements
3.Compund statements
4.Inout statements
5.Output statements

7 控制语句

if-else
语法: if (condition){then-body} else {[else-body]}
例子:
awk -F: ‘{if ($1==”root”) printf “%-15s:%s\n”,$1,”Admin”;else printf “%-15s:%s\n”,$1,”Common user”}’ /etc/passwd
image.png
while
语法: while (condition){statement1;statement2;…}
awk -F: ‘{i=1 while(i<=NF){if (length($i)>=4) {print $i};i++}}’ /etc/passwd
image.png
do-while
语法: do {statement1;statement2;….} while (condition)
awk -F: ‘{i=1; do {print $i;i++} while(i<=3)}’ /etc/passwd
image.png
for
语法:for (variable assignment;condition;iteration process){statement1,statement2,…}
awk -F: ‘{for (i=1;i<=3;i++) print $i}’ /etc/passwd
image.png
for循环还可以用来遍历数组元素,
语法:for (i in array){statement1;statement2;…}
awk -F: ‘$NF!~/^$/{BASH[$NF]++}END{for(A in BASH){printf “%15s:%i\n”,A,BASH[A]}}’ /etc/passwd
case
语法 switch (expression) {case VALUE or /REGEXP/:statement1,statement2,…default:statement1,statement2,….}
break和continue
常用于循环和case语句
next
提前结束对本行文本的处理,并接着处理下一行,例如:下面的命令将显示其ID号为奇数的用户;
awk -F: ‘{if($3%2==0) next;print $1,$3}’ /etc/passwd
image.png

8 数组

array[index-expression]
index-expression可以使用任意字符串。需要注意的是,如果某数组元素事先不存在,那么在引用其时,awk会自动创建此元素并初始化为空串。因比。要判断某数组中是否存在某元素,所要使用index in array的方式。
要遍历数组中的每一个元素,需要使用如下的特殊结构:for (var in array) { statement1, …}其中, var用于引用教组下标,而不是元素值:
例子:
netstat -ant | awk ‘/^tcp/{++S[$NF]} END (for(a in S) print a..S[a]}’
每出现一被/^tcp/模式匹配到的行,数组S[$NF]就加i,NF为当前匹配到的行的最后一个字段,此处用其值做为数组S的元素索引:
awk ‘{counts[$1]++}; END {for(url in counts) print counts[url],url}’/var/log/httpd/access_log
用法与上一个例子相同,用于统计某日志文件中IIP地址的访问量
[root@web01 nginx]# awk ‘BEGIN{print “IP地址 访问次数”}{count[$1]++}END{for(ip in count){print ip,count[ip]}}’ /var/log/nginx/access.log-20210112
IP地址 访问次数
10.0.0.1 2
image.png
统计TCP各个连接状态的数量
[root@web01 ~]# netstat -tna | awk ‘/^tcp/{state[$NF]++}END{for(S in state) {print S,state[S]}}’
image.png