awk用于处理结构化的数据比如数据报表,一种文本处理功能强大的编程语言。
Linux下的/etc/passwd文件拿来当试手的例子非常合适。
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
这是我取我机器上这个文件的前5行,用来做测试
$ awk -F ":" '{ print }' passwd
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
$ awk -F ":" '{ print $0 }' passwd 得到的结果和上面一摸一样
$ awk -F ":" '{print $1,$2}' passwd
root x
bin x
daemon x
adm x
lp x
-F ":"表示以:为分割符号,默认以空格分割。$0表示当前的整个行,而$1,$2...则相应代表分割后的列
逗号则让列与列之间插入空格
$ awk -F ":" '{print $1 $2}' passwd
rootx
binx
daemonx
admx
lpx
也可以使用插入字符来到达格式化的效果,$ awk -F ":" '{print $1 ” “ $2}' passwd和$ awk -F ":" '{print $1,$2}' passwd得到的结果是一样的
$ awk -F ":" '/root/{print "uid:" $3}' passwd
uid:0
这里使用了正则匹配,含有root的行输出第三列,这里就是uid
$ awk -F ":" '/^(root|bin)/{print $1}' passwd
root
bin
匹配以root或bin开头的行
$ awk -F ":" '$3==0 {print $0}' passwd
root:x:0:0:root:/root:/bin/bash
可以使用表达式,当uid等于0时输出这一行
还可以做数值运算
$ awk -F ":" '$3==0 {print $3+10}' passwd
10
$ awk -F ":" '{print ($3 > 1 ? "yes":"no")}' passwd
no
no
yes
yes
yes
$ awk -F ":" '/^root/,/^daemon/{print $0}' passwd
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
匹配以root开头的行到以daemon开头的行,如果没有以daemon开头的行则将打印到文件末尾
$ awk -F ":" '$1~/bin/{i=$3+$4; print "i=" i}' passwd
i=2
既然awk是一种编程语言,我们就能够使用变量,上面就是匹配第一列以bin开头的行,取出第三和第四列相加赋值给i然后打印
我们还可以将在命令行中赋值的变量带到awk脚本中
$ awk -F ":" -f script i=1 j=2 passwd
这样在脚本script中可以使用i和j,它们分别被赋值1和2,这和在脚本中定义变量是一样的
$ awk 'BEGIN{FS=":"; OFS=" "; ORS="\n"} {print $1} END{print NR}' passwd
root
bin
daemon
adm
lp
5
BEGIN和END中的代码快分别在匹配文件之前和之后执行,FS,OFS,ORS,NR都是awk的内建变量
上例的意思是将分割符设为:,输出分割符为空格,换行符为行之间的分隔符,NR代表匹配的行数
$ awk -F ":" '$3==0 {print $0 > "root.txt" }' passwd
使用重定向将结果输出到root.txt中
$ awk -F ":" '{if($3==0){print "yes"} else {print "no"}}' passwd
yes
no
no
no
no
awk中的条件判断语句
if(expr){
statment;
}else{
statment;
}
$ awk -F ":" '$1~/root/{for (i=1; i < NF; i++) print i,$i}' passwd
1 root
2 x
3 0
4 0
5 root
6 /root
for循环语句
awk -F ":" '$1~/root/{i=1;while(i < NF){print i,$i;i++}}' passwd
使用while打印出与上面的for语句一样的结果
$ awk -F ":" '{gsub(/root/, "david"); print}' passwd
david:x:0:0:david:/david:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
使用awk的内建函数,将root替换为david
参考文档:
IBM的awk实例
http://www-128.ibm.com/developerworks/cn/linux/shell/awk/awk-1/
http://www-128.ibm.com/developerworks/cn/linux/shell/awk/awk-2/
http://www-128.ibm.com/developerworks/cn/linux/shell/awk/awk-3/
阅读(2299) | 评论(0) | 转发(1) |