AWK是一种优良的文本处理工具,Linux及Unix环境中现有的功能最强大的数据处理引擎之一,可以进行正则表达式的匹配,样式装入、流控制、数学运算符、进程控制语句甚至于内置的变量和函数
1.基本语法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| awk 'BEGIN{} {} END{}' file awk ‘BEGIN {print “Hello, world”}’ file awk ‘END {print “Hello, world”}' file # END模式用于的最后一个输入行读入之前要执行的操作,并不会对输入行进行操作
awk -f script file # -f 指定awk脚本文件
awk -F':' '{print $1}' file # -F 指定分割符,若没指定,默认为空格
awk ‘{print $1}’ file # $1 打印文件全部的第一个字段
awk ‘/re/’ file # 打印匹配到re的每一行
awk '{printf("%d\t%s\n",$5,$9)}' file # 格式化输出
|
2.匹配模式
1 2 3 4 5
| awk ‘/^$/ {print “This is a blank line”}’ file awk ‘$5~/^MA/’ {print “This a MA”}' file # 正则匹配$5字段
|
3.操作符
算数操作符:
1 2 3 4 5 6
| + 加 - 减 * 乘 / 除 % 取模 ^ 去幂
|
布尔操作符:
4.正则字符
元字符:
1 2 3 4 5 6 7 8
| . 匹配除换行以外的任意单个字符 * 匹配任意个(包括0个)在他前面的字符 [0-9] 匹配数字0-9,如果方括号内第一个为^表示否定匹配,匹配方括号中任意一个元素 [a-z] 匹配字母a-z,如果方括号内第一个为^表示否定匹配,匹配方括号中任意一个元素 ^ 匹配开头 $ 匹配结尾 \ 转义特殊字符和元字符 \{2,4\} 匹配2-4个他前面的字符
|
特殊字符:
1 2 3 4 5 6
| + 匹配前面的正则表达式一次或多次出现 ? 零次或者一次 | 或前后满足其一 () 正则分组 (?<=) 非获取匹配,逆向取 (?=) 非获取匹配,正向取
|
POSIX字符类:
1 2 3 4 5 6 7
| [:alnum:] 可打印字符 [:alpha:] 字母字符 [:blank:] 空格和制表符 [:digit:] 数字字符 [:lower:] 小写字符 [:punct:] 标点符号字符 [:upper:] 大写字符
|
5.拓展用法
传递参数:
1 2
| awk ‘$NF~search{print $0}’ search=name file 将shell中name参数传入awk中
|
条件表达式:
1
| if(expression){action1;action2};esle if action; else action
|
循环:
1 2 3 4 5 6 7 8 9 10 11
| BEGIN{i=1;while(i<=4){action1;action2}} BEGIN{do {i++;print i}while(i<4)} for(i=1;i<NF;i++) action
|
next:下一行的操作
1 2 3 4
| if(expression)next; action awk 'FILENAME=="file1"{a++;next}{print $0}'END'{print a}' file1 file2 统计file1的行数,打印file2
|
数组
1 2 3 4 5 6 7 8 9 10 11 12
| array[NR]=$2 存入每行的$2字段的值 for(x=1;x<=NR;x++)action1 item in array 如果array[item]存在就返回1,否则就返回0 delete array[]
|
关联数组
1 2 3 4 5 6 7 8
| array[$1]+=$2 若$1相同,则累加$2 for(i in array) print i,a[i] $ awk -F'\t' '{a[$12]+=$23} END{for (i in a)print a[i],i}'
|
函数
1 2 3 4 5 6 7 8 9 10 11
| split($1,fullname," ") 用split创建分割数组,$1表示需要分割的字段,fullname表示数组名字," "表示用什么作为分隔符 rand() 返回随机数 0=<r<1 gsub(r,s,t) t字符串中r正则匹配用字符串s替换 全局的sub(r,s,t)替换首个出现的 length(s) 返回字符串长度
|
6.使用例子
有一份学生成绩表,根据学生成绩表,打印学生姓名,平均分,等级
A 100~90
B 89~80
C 79~70
D 69~0
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| $ cat grades mona 70 77 85 83 70 89 john 85 92 78 94 88 91 andrea 89 92 78 94 88 91 jasper 84 88 80 92 84 82 dunce 64 80 60 60 61 62 ellis 90 98 89 96 96 92 $ awk '{total=0;for(i=2;i<=NF;i++) total+=$i;avg=total/(NF-1);if(avg>=90) grade="A";else if(avg>=80) grade ="B";else if(avg>=70)grade="C";else if(avg>=60)grade="D";else grade="F";++a[grade];print $1,avg,grade}' grades mona 79 C john 88 B andrea 90.5 A jasper 85 B dunce 64.5 D ellis 93.5 A
|