Shell文本处理三剑客之一awk(2)
- 表达式
与其他编程语言一样,awk表达式用于存储,操作和获取数据
一个awk表达式可由数值,字符常量,变量,操作符函数和正则表达式自由组合而成
变量是一个值的标识符,定义awk变量非常方便,只需定义一个变量名并将值赋给它即可
#变量名只能包含字母,数字和下划线,而且不能以数字开头
#定义awk变量无需声明变量类型,每个变量有两种类型的值:字符串值和数值
#awk根据表达式上下文来确定使用哪个值
#变量的默认数值为0,默认字符串值为空
这里匹配的是从开头到结尾(x刚开始的默认值是0,x++ 表示先返回x的值再给x加一):
[root@localhost awk]# awk '/^$/{print x++}' input
0
1
2
++x 表示x值先增加1再返回x的值,这个命令的意义:统计我们input文件的空行数
[root@localhost awk]# awk '/^$/{print ++x}' input
1
2
3
平均值的计算
[root@localhost awk]# cat stucode
Tom,Li,028-123456789,85,92,97,88
Tom,Li,028-123456789,85,92,97,88
Tom,Li,028-123456789,85,92,97,88
[root@localhost awk]# cat scr2.awk
#!/usr/bin/awk -f
BEGIN {FS=","}
{total=$4+$5+$6+$7
avg=total/4
print $1,avg
}
[root@localhost awk]# chmod +x scr2.awk
[root@localhost awk]# ./scr2.awk stucode
Tom 90.5
Tom 90.5
Tom 90.5
- 系统变量
awk定义了很多内建(内置)变量用于设置环境信息,我们称它为系统变量
这些系统变量可分为:
第一种用于改变awk的默认值,如域分隔符
第二种用于定义系统值,在处理文本时可以读取这些系统值
如 : 记录中的域数里量(NF),当前记录数(NR),当前文件名(FILENAME)等
参数解释:
#NF:为记录的域数量
#NR:显示当前的记录数,该值根据读取输入文件的进读而变化,读取第一条记录时,NR=1读取到文件末尾时,NR为该文件所包含的记录数
#$0:标示打印记录的所有域
#FILENAME:保存了当前的输入文件名
[root@localhost awk]# awk 'BEGIN {FS=","} {print NF,NR,$0} END {print FILENAME}' stucode #因为是按行处理,所以每处理完一行,当前记录数加一
7 1 Tom,Li,028-123456789,85,92,97,88
7 2 Tom,Li,028-123456789,85,92,97,88
7 3 Tom,Li,028-123456789,85,92,97,88
- awk的格式化输出
前面的例子只涉及awk如何输入文件进行处理,对于输出的格式并未规定
而awk的一大主要功能是产生报表
报表就是要按照一定的格式输出,awk借鉴
C语言的语法,定义了printf输出语句,它可以规定输出的格式
{printf("%s\t%d\n",$2,$8)}
[root@localhost awk]# cat stucode
Tom,Li,028-123456789,85,92,97,88
Tom,Li,028-123456789,85,92,97,88
Tom,Li,028-123456789,85,92,97,88
[root@localhost awk]# awk 'BEGIN {FS=","} {printf("%s\t%d\n",$2,$8)}' stucode
Li 0
Li 0
Li 0
每搜索每个输入文件的行之前先输出一个A:65,a:97
[root@localhost awk]# awk 'BEGIN {printf("%c\n",65)}' stucode
A
[root@localhost awk]# awk ' {printf("%c\n",65)}' stucode
A
A
A
%f %.3f
#默认浮点数的精度是保留小数点后6位,整数前面如果小数点,表示小数点保留整数位
%-15s
#对字符串的格式进行修饰 - 表示左对齐,+表示右对齐,15(整数)表示字符串的长度最长不超过15位,若字符串不够15位则用空格去补齐
[root@localhost awk]# awk 'BEGIN {printf("%f\n",2020)}'
2020.000000
[root@localhost awk]# awk 'BEGIN {printf("%.3f\n",2020.564646546)}'
2020.565
[root@localhost awk]# awk 'BEGIN {FS=","} {printf("%-15s\t%s\n",$1,$3)}' stucode
Tom 028-123456789
Tom 028-123456789
Tom 028-123456789
- awk的内置字符串函数(替换==更改)
awk提供了强大的内置字符串函数,用于实现文本的字符串替换,查找以及分割等功能
- gsub函数执行字符串替换功能,它将第一个字符串替换为第二个字符串
- Index和length函数的用法
Index返回第二个字符在第一个字符出现的首位置,两个参数:两个字符串(每个字符串用双引号包括,两个参数之间用逗号隔开)
length返回字符串的长度,
(1)gsub替换函数,3个参数,第一个是需要替换的域中的字符,
第二个是替换成的字符,第三个是需要操作的域
OFS=”:” #OFS(output FS)表示,
指定替换完后输出的分隔符是冒号(默认是空格)
可以更改替换某个域上的部分字符串(很实用)
替换第一个域上的root字符串为dd
[root@localhost awk]# awk 'BEGIN {FS=":"} gsub(/root/,"dd",$1) {print $0}' passwd
dd x 0 0 root /root /bin/bash #默认OFS的值是空格
[root@localhost awk]# awk 'BEGIN {FS=":";OFS=":"} gsub(/root/,"dd",$1) {print $0}' passwd
dd:x:0:0:root:/root:/bin/bash
更改所有域上的root为dd
[root@localhost awk]# awk 'BEGIN {FS=":"} gsub(/root/,"dd",$0) {print $0}' passwd
dd:x:0:0:dd:/dd:/bin/bash
operator:x:11:0:operator:/dd:/sbin/nologin
[root@localhost awk]# awk 'BEGIN {FS=":";OFS=":"} gsub(/roo/,"hehehe",$1) {print $0}' passwd
hehehet:x:0:0:root:/root:/bin/bash
(2)index索引函数用法,Index返回第二个字符在第一个字符出现的首位置,
两个参数:两个字符串(每个字符串用双引号包括,两个参数之间用逗号隔开)
[root@localhost awk]# awk 'BEGIN {print index("gridsphere","ph")}'
6
[root@localhost awk]# awk 'BEGIN {print length("gridsphere")}'
10
(3)lenglth函数一个参数,是个字符串用双引号””包起来