AWK编程
基本用法:
1 awk记录和域
awk认为输入文件是结构化的,awk将每个输入文件行定义为记录,行中的每个字符串定义为域,域之间用空格、Tab键或其他符号进行分割,分割域的符号就叫分隔符 (默认分割符是空格!!!!) eg :
sturecord文件: zhangsan 22 beijing 010 lisi 23 wuhan 027
wangwu 23 shenyang 024
此处分别有四个域 ,分割符是空格
eg : awk '{print $2,$1,$4,$3}' file1 结果:。 22 zhangsan 010 beijing 23 lisi 027 wuhan 23 wangwu 024 shenyang ($1 代表第一域! $2第二 依次类推,而 $0 代表所有 即全域!!!!!)
eg : awk '{print $0}' file1
结果:
zhangsan 22 beijing 010
lisi 23 wuhan 027
wangwu 23 shenyang 024
2 awk修改分割符 两种方式: -F , FS变量
(1)-F 例子 eg : file内容为: zhang san 21 beijing 010 li si 23 wuhan 027 wang wu 22 chengdu 024 只有姓名之间是空格, 其余之间是tab 默认情况下空格是分割符 所以这样只有两个域 第一域 zhang 第二域: san 21 beijing 010 如果要以tab为分割符,则 zhang san 这样被看作是一个域 命令: awk -F"\t" '{print $2}' file2 结果: 21 23 22
(2)FS变量: 文件内容: zhang san,21,beijing,010 li si,23,wuhan,027 wang wu,22,chengdu,024 eg : awk 'BEGIN {FS=","} {print $2,$3}' file3 结果: 21 beijing 23 wuhan 22 chengdu
awk 以 域和记录来处理文件的
sed处理的是流!!!!!!!!
3awk关系、布尔运算符、表达式:运算符 意义< 小于> 大于<= 小于等于>= 大于等于== 等于!= 不等于~ 匹配正则表达式!~ 不匹配正则表达式运算符 意义|| 逻辑或&& 逻辑与! 逻辑非
与其他编程语言一样,awk表达式用于存储、操作和获取数据,一个awk表达式可由数值、字符常量、变量、操作符、函数和正则表达式自由组合而成变量是一个值的标识符,定义awk变量非常方便,只需定义一个变量名并将值赋给它即可。变量名只能包含字母、数字和下划线,而且不能以数字开头运算符 意义+ 加- 减* 乘/ 除% 模^或** 乘方++x 在返回x值之前,x变量加1x++ 在返回x值之后,x变量加1
例子: 以etc下的passwd文件为例子
1 正则表达式eg: awk 'BEGIN {FS=”:”} $0~/root/' passwd (在passwd文件中查找 以:为分割符,全域$0与root(这个是正则表达式)匹配的行) 结果:root:x:0:0:root:/root:/bin/bash eg: awk 'BEGIN {FS=”:”} $0!~/root/' passwd (在passwd中查找 全域 不与root匹配的行)2运算符 eg awk 'BEGIN {FS=”:”} {if($3==7||$4==7) print $0}' passwd 将第三域 或者 第四域 等于7 的记录打印出来 结果: awk: 1: unexpected character 0xe2 eg : awk 'BEGIN {FS=":"} {if($3~7||$4~7) print $0}' passwd 将第三域 或者 第四域 包含7 的记录打印出来 结果: lp:x:7:7:lp:/var/spool/lpd:/bin/sh avahi-autoipd:x:106:117:Avahi autoip daemon,,,:/var/lib/avahi-autoipd:/bin/false avahi:x:107:118:Avahi mDNS daemon,,,:/var/run/avahi-daemon:/bin/false hplip:x:113:7:HPLIP system user,,,:/var/run/hplip:/bin/false sshd:x:117:65534::/var/run/sshd:/usr/sbin/nologin
=与~区别:!! = 表示 某个域与 7 当作值全域比较!! 相等!!! 而~表示 的是 正则表达式!!!! 匹配的是字符串!!!
eg: awk '/^$/{print x+=1}' file 等价于: awk '{$0~/^$/} {print x+=1}' file awk '{/^$/} {print x+=1}' file 找出file1中的空白行,找到一个空白行 x就加1 eg: file4的内同: zhangsan class7 2009,91,92,90 lisi class6 2009,88,87,95 wangwu class1 2008,91,98,85 file3,awk的内容: #!/usr/bin/awk -f BEGIN {FS=","} {total=$2+$3+$4 avg=total/5 print $1,avg} (计算每个学生的平均成绩) 执行:./file3.awk file 结果: zhangsan class7 2009 54.6 lisi class6 2009 54 wangwu class1 2008 54.8
4awk系统变量:awk定义了很多 内建变量用于 设置环境信息,我们称它们为系统变量,这些系统变量可分为两种:第1种用于 改变awk的缺省值,如域分隔符;第2种用于 定义系统值,在处理文本时可以读取这些系统值,如记录中的 域数量、当前记录数、当前文件名等,awk 动态改变第2种系统变量的值变量名 意义$n 当前记录的第n个域,域间由FS分割$0 记录的所有域ARGC 命令行参数的数量ARGIND 命令行中当前文件的位置(以0开始标号)ARGV 命令行参数的数组CONVFMT 数字转换格式ENVIRON 环境变量关联数组ERRNO 最后一个系统错误的描述FIELDWIDTHS 字段宽度列表,以空格键分割FILENAME 当前文件名FNR 浏览文件的记录数file number row FS 字段分隔符,默认是空格键 FieldSign IGNORECASE 布尔变量,如果为真,则进行忽略大小写的匹配NF 当前记录中的域数量NR 当前记录数OFMT 数字的输出格式OFS 输出域分隔符,默认是空格键ORS 输出记录分隔符,默认是换行符RLENGTH 由match函数所匹配的字符串长度RS 记录分隔符,默认是空格键RSTART 由match函数所匹配的字符串的第1个位置SUBSEP 数组下标分隔符,默认值是\034eg: awk 'BEGIN {FS=”:”} {print NF,NR,$0} END {print FILENAME}' file4 结果: 4 1 zhangsan class7 2009,91,92,90 4 2 lisi class6 2009,88,87,95 4 3 wangwu class1 2008,91,98,85 0 4
5awk格式化输出:awk的一大主要功能是 产生报表, 报表就要求按照预定的格式输出,awk借鉴C语言的语法,定义了printf输出语句,它可以规定输出的格式。printf: printf (格式控制符,参数) 格式控制符 : awk修饰符,格式符修饰符 意义- 左对齐width 域的步长.prec 小数点右边的位数运算符 意义%c ASCII字符%d 整型数%e 浮点数,科学记数法%f 浮点数%o 八进制数%s 字符串%x 十六进制数
Eg 文件内容: zhang san,21,beijing,010 li si,23,wuhan,027 wang wu,22,chengdu,024
eg: awk 'BEGIN {FS=”,”} {printf(“%s\t%d\n”,$1,$2)}' file3 (将第一域为字符串 第二域为数字 打印出来) 结果: zhang san 21 li si 23 wang wu 22 eg: awk 'BEGIN {FS=”,”} {printf(“%-10s\t\t%s\n”,$1,$3)}' file3 (红色表示 该所占位置为10个字符!) 结果: zhang san beijing li si wuhan wang wu chengdu eg awk 'BEGIN {FS=",";print "NAME\t\t\tCITY"} {printf("%-10s\t\t%s\n",$1,$3)}' file3 (第一个{}中的两个命令中间是;分号 后面 红色的命令是打印出 列名) 结果; NAME CITY zhang san beijing li si wuhan wang wu chengdu