1.awk和sed的区别
awk更像脚本语言,且更适合比较规范的文本处理
2.awk脚本的流程控制
BEGIN{ 命令 } #初始代码块,主要和变量相关
/pattern/{ 命令 } #pattern正则匹配、执行代码块
END{ 命令 } #结束代码块,主要和信息输出相关
3.awk的字段引用和分离
记录和字段
-
每行称作awk记录
-
使用空格,制表符分隔的单词称作字段
-
可以自己指定分离的字段
字段的引用
- $0:显示当前行所有内容
- n : 显 示 当 前 行 的 第 n 列 内 容 , 如 果 存 在 多 个 n:显示当前行的第n列内容,如果存在多个 n:显示当前行的第n列内容,如果存在多个n,它们之间使用逗号(,)隔开
- -F 选项改变字段分隔符,分隔符可以使用正则表达式
4.awk的表达式
-
赋值操作
- =最常用的赋值操作
- ++ – += -= *= /= %= ^=
-
算数操作
- ±*/%^
-
系统变量
变量名 含义 FS,OFS FS输入文件的字段分隔符默认是连续的空格和tab,OFS输出字段分隔符默认是连续的空格和tab NR,FNR NR已经读出的记录数,就是行号,FNR从1开始,各文件分别计数的行号 NF 字段数量,最后一个字段内容可以用$NF取出 RS 记录分隔符默认是换行符 -
关系操作符
< > <= >= ==!= ~ !~
-
布尔操作
&& || !
5.awk的条件循环
-
条件语句
if(表达式){ } else{ }
-
循环
-
while循环
while (表达式) awk语句
-
do 循环
do{ awk 语句 }while(表达式)
-
for循环
for (初始值;循环判断条件;累加) awk语句1
影响控制的其他语句:break,continue
-
6.awk数组
-
数组的定义
- 一组有某种关联的数据,通过下标依次访问
- 数组名[小标]=值,下标可以使用字符串
-
数组的遍历
- for (变量 in 数组名)
-
删除数组
- delete数组[下标]
-
命令行参数数组
- ARGC;
- ARGV
7.awk函数
-
算数函数
-
sin() cos()
-
int()
-
rand() srand()
-
-
字符串函数
-
gsub(r,s,t)
-
index(s,t)
-
length(s)
-
match(s,r)
-
split(s,a,sep)
-
sub(r,s,t)
-
substr(s,p,n)
-
-
自定义函数
function 函数名(参数){ awk 语句 return awk变量 }
8.实践
1.基本实践
awk '/^menu/{print $0}' /boot/grub2/grub.cfg
awk -F "'" '/^menu/{print $0}' /boot/grub2/grub.cfg
awk -F "'" '/^menu/{print $2}' /boot/grub2/grub.cfg
awk -F "'" '/^menu/{print x++,$2}' /boot/grub2/grub.cfg
2.awk的表达式
head -5 /etc/passwd | awk 'BEGIN{RS=":"}{print $0}'
awk '{print NR,$0}' /etc/hosts /etc/hosts
awk '{print FNR,$0}' /etc/hosts /etc/hosts
head -5 /etc/passwd | awk 'BEGIN{FS=":"}{print NF}'
head -5 /etc/passwd | awk 'BEGIN{FS=":"}{print $NF}'
3.awk的条件循环
# cat kpi.txt
user1 70 72 74 76 74 72
user2 80 82 84 82 80 78
user3 60 61 62 63 64 65
user4 90 89 88 87 86 85
user5 45 60 63 62 61 50
head -1 kpi.txt |awk '{for (c=2;c<=NF;c++) print c}'
head -1 kpi.txt |awk '{for (c=2;c<=NF;c++) print $c}'
head -1 kpi.txt |awk '{sum=0;for (c=2;c<=NF;c++) print $c;print sum/(NF-1)}' kpi.txt
head -1 kpi.txt |awk '{sum=0;for (c=2;c<=NF;c++) sum+=$c;print sum/(NF-1)}' kpi.txt
4.awk数组
head -1 kpi.txt |awk '{sum=0;for (c=2;c<=NF;c++) sum+=$c;print sum/(NF-1)}' kpi.txt
awk '{ sum=0 ; for (column=2; column<=NF;column++) sum+=$column; average[$1]=sum/(NF-1)}END{ for(user in average)print user,average[user]}' kpi.txt
#vi arg.awk
BEGIN{
for (x=0;x<ARGC;x++)
print ARGV[x]
print ARGC
}
#awk -f arg.awk 11 22 33
#vi result.awk
{
sum = 0
for( column = 2 ; column <= NF; column++ )
sum += $column
average[$1] = sum / ( NF - 1 )
if( average[$1] >= 80 )
letter = "S"
else if( average[$1] >= 70 )
letter = "A"
else if( average[$1] >= 60 )
letter = "B"
else
letter = "C"
print $1,average[$1],letter
letter_all[letter]++
}
END{
for( user in average )
sum_all += average[user]
avg_all = sum_all / NR
print "average all:",avg_all
for( user in average )
if( average[user] > avg_all )
above++
else
below++
print "above",above
print "below",below
print "S:",letter_all["S"]
print "A:",letter_all["A"]
print "B:",letter_all["B"]
print "C:",letter_all["C"]
}
#awk -f result.awk kpi.txt
5.awk函数
awk 'BEGIN{pi=3.14;print int(pi)}'
awk 'BEGIN{print srand();rand()}'
awk 'function a(){return 0}BEGIN{ printa()}'