初学awk
1. awk简介
awk是一种编程语言,使用用在Unix/Linux下对文本和数据进行处理。awk是有三个人做成,即Alfred Aho、Brian Kernighan、Peter Weinberger。它支持正则表达式和用户自定义函数。
2 应用
awk option ‘program’ var
awk option -f program-file var
这里的var 可以指文件(file)或者value
他的常用选项有
-F 或者 –filed-separator
意思是指定输入文件拆分隔符
例子
实际上我们从文件中找到分隔符
从 /etc/passwd 下我们看到了以冒号分割 #awk –F:’{print $1,$2}’ /etc/passwd 指取出前两段,当然也可这样用
[root@station90 ~]# head /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
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
[root@station90 ~]# head /etc/passwd |awk -F: '{print $1,$2}'
root x
bin x
daemon x
adm x
lp x
sync x
shutdown x
halt x
mail x
news x
-v var=value 或者 –asign var=value
赋值一个变量值
例子
[root@station90 ~]# head /etc/passwd|awk -v FS=[0-9] '{print $1}'
root:x:
bin:x:
daemon:x:
adm:x:
lp:x:
sync:x:
shutdown:x:
halt:x:
mail:x:
news:x:
可以看出这里我们用了正则表达式。注意里面的FS是内置变量 FS 字段分隔符 此时可能会问$1是什么$1当前记录的第1个字段
其实这里是$n也是内置变量。
-f programfile 或者 –file programfile
从脚本文件中读取awk命令。
这里就不再演示了
3接下来我了解一下他的内置变量
$n | 当前记录的第n个字段,字段间由FS分隔。 |
$0 | 完整的输入记录。 |
ARGC | 命令行参数的数目。 |
ARGV | 包含命令行参数的数组。 |
FILENAME | 当前文件名。 |
FNR | 同NR,但相对于当前文件。 |
FS | 字段分隔符(默认是任何空格)。 |
NF | 当前记录中的字段数。 |
NR | 当前记录数。 |
OFS | 输出字段分隔符(默认值是一个空格)。 |
ORS | 输出记录分隔符(默认值是一个换行符)。 |
RS | 记录分隔符(默认是一个换行符)。 |
现在我们去练习几个
[root@station90 ~]# head /etc/passwd|awk -F: -v ORS=" " '{print $1,$2}'
root x bin x daemon x adm x lp x sync x shutdown x halt x mail x news x
上面我们指定了输出记录分隔符为分号中的空格
[root@station90 ~]# head /etc/passwd|awk -F: -v OFS="***" -v ORS="/n" '{print $1,$2}'
root***x
bin***x
daemon***x
adm***x
lp***x
sync***x
shutdown***x
halt***x
mail***x
news***x
上面我们用了OFS指输出段分隔符我们定义了*
[root@station90 ~]# head /etc/passwd|awk -F: '{print OFS,$1,$2}'
root x
bin x
daemon x
adm x
lp x
sync x
shutdown x
halt x
mail x
news x
可以看到我们可以应用到花括号里面。好玩吧!
[root@station90 ~]# head /etc/passwd|awk -F: '{print OFS="***",$1,$2}'
******root***x
******bin***x
******daemon***x
******adm***x
******lp***x
******sync***x
******shutdown***x
******halt***x
******mail***x
******news***x
这里注意和上面的区别。
[root@station90 ~]# head /etc/passwd|awk -F: '{print OFS="*",NR,$1,$2}'
**1*root*x
**2*bin*x
**3*daemon*x
**4*adm*x
**5*lp*x
**6*sync*x
**7*shutdown*x
**8*halt*x
**9*mail*x
**10*news*x
NR指当前的记录数看十行,如果有连续几个文件则会累加记录.
[root@station90 ~]# awk -F: '{print OFS="*",NR,FNR,$1,$2}' /etc/passwd /etc/shadow
**1*1*root*x
**2*2*bin*x
**3*3*daemon*x
**4*4*adm*x
**5*5*lp*x
**6*6*sync*x
**7*7*shutdown*x
**8*8*halt*x
**9*9*mail*x
**10*10*news*x
**11*11*uucp*x
**12*12*operator*x
**13*13*games*x
**14*14*gopher*x
**15*15*ftp*x
**16*16*nobody*x
**17*17*vcsa*x
**18*18*rpc*x
**19*19*mailnull*x
**20*20*smmsp*x
**21*21*nscd*x
**22*22*oprofile*x
**23*23*pcap*x
**24*24*ntp*x
**25*25*dbus*x
**26*26*avahi*x
**27*27*xfs*x
**28*28*rpcuser*x
**29*29*nfsnobody*x
**30*30*sshd*x
**31*31*haldaemon*x
**32*32*gdm*x
**33*33*avahi-autoipd*x
**34*34*student*x
**35*35*visitor*x
**36*36*a*x
**37*37*user1*x
**38*38*dovecot*x
**39*39*redhat*x
**40*40*hhh*x
**41*41*yyy*x
**42*42*wo*x
**43*43*ppp*x
**44*44*fff*x
**45*1*root*$1$0ESR.Vg2$4pNrcTpvjbo2OTEbVNi371
**46*2*bin**
**47*3*daemon**
**48*4*adm**
**49*5*lp**
**50*6*sync**
**51*7*shutdown**
**52*8*halt**
**53*9*mail**
**54*10*news**
**55*11*uucp**
**56*12*operator**
**57*13*games**
**58*14*gopher**
**59*15*ftp**
**60*16*nobody**
**61*17*vcsa*!!
**62*18*rpc*!!
**63*19*mailnull*!!
**64*20*smmsp*!!
**65*21*nscd*!!
**66*22*oprofile*!!
**67*23*pcap*!!
**68*24*ntp*!!
**69*25*dbus*!!
**70*26*avahi*!!
**71*27*xfs*!!
**72*28*rpcuser*!!
**73*29*nfsnobody*!!
**74*30*sshd*!!
**75*31*haldaemon*!!
**76*32*gdm*!!
**77*33*avahi-autoipd*!!
**78*34*student*$1$t0r1eGvJ$Jpjj3Bqo9GQ.7wQlqUgQg1
**79*35*visitor*$1$0OLhCNJa$uWdi0j9xPnRfsrZN/B5qU/
**80*36*a*$1$wbSE01p5$zmbzKDPJSZdz67O3bPHtK0
**81*37*user1*$1$vAbHy10v$ZNRHCB/Extv3VxMwwL7rj/
**82*38*dovecot*!!
**83*39*redhat*$1$yFUSivQX$GyLeXUDWHY6i9SNVvIKUS.
**84*40*hhh*!!
**85*41*yyy*$1$C1Kt9o0a$mWm7hh3vEivBNCHYsfFQD.
**86*42*wo*$1$ibF/pWF7$Z46.CNwegtr8U0LQ8Ng2R/
**87*43*ppp*!!
**88*44*fff*!!
注意第二列为FNR的记录数他只记录当前文件的行数可和NR区分一下
[root@station90 ~]# awk -F: 'BEGIN{print ARGC} {print OFS="*",NR,FNR,$1,$2}' /etc/passwd /etc/shadow
3
这里我截取了一些分析一下,这里的3 就是ARGC的值,我们这里用了BEGIN这个模块,参数是awk /etc/passwd /etc/shadow
我们可以用ARGV[N]这里N为数组值的下标。
[root@station90 ~]# awk -F: 'BEGIN{print ARGC,ARGV[1],"HOHOBB"}' /etc/passwd
2 /etc/passwd HOHOBB
这次知道那些是参数了吧!
接下来我们应用一下正则表达式
/<
匹配一个单词的开头的空字符串,锚定开始。
/>
匹配一个单词的末尾的空字符串,锚定末尾。
. | 匹配除换行符以外的任意字符 |
/w | 匹配字母或数字或下划线或汉字 |
/s | 匹配任意的空白符 |
/d | 匹配数字 |
/b | 匹配单词的开始或结束 |
^ | 匹配字符串的开始 |
$ | 匹配字符串的结束 |
^/w+匹配一行的第一个单词
[root@station90 ~]# head /etc/passwd| awk -F: '/^/w+/{print $1,$2}'
root x
bin x
daemon x
adm x
lp x
sync x
shutdown x
halt x
mail x
news x
这里我们用了^/w+不过不用也是如此。
[root@station90 ~]# head /etc/passwd| awk -F: '/^root/{print $1,$2}'
root x
[root@station90 ~]# head /etc/passwd| awk -F: '/^ro.*/{print $1,$2}'
root x
接下来我们来了解一下awk的编程
先看if语句
{if (expression){
statement; statement; ...
}
}
[root@station90 ~]# awk -F: '{if ($1 <$2) print $2 "too high"}' /etc/passwd
xtoo high
xtoo high
xtoo high
xtoo high
xtoo high
xtoo high
xtoo high
xtoo high
{if (expression){
statement; statement; ...
}
else{
statement; statement; ...
}
}
这里就不再举例了
这里我们再看一下循环语句
[root@station90 ~]# awk '{ i = 1;sum=0; while ( i <= 100 ) { print sum+=i; i++} {pint sum}}' /etc/passwd |less
还有for语句
#awk '{for (i = 1; i<NF; i++) print NF,$i}' test
test表示文件名
好了awk就介绍这么多吧,呵呵…..