Linux awk 进阶

       在Linux awk语言中,提供了很多有意义的函数。例如:

       gsub(r,s)  在整个$0中用s代替r

       gsub(r,s,t) 在整个t上用s代替r

       length(s)   返回s的长度

       index(s,t)   返回s中字符串t的第一位置

       match(s,r)   测试s是否包含r 子串

       spilt(s,a,fs)  用fs(某种分割符号)去拆分s串,将拆分后的数组赋给a

       sub(r,s)        用$0中最左边最长的子串去代替s

       substr(s,p)   返回字符串s从p开始的后缀部分

       substr(s,p,n)   返回字符串s从p开始的长度为n的串

 

       现在分别举例子来看这些具体的应用:

 

      1:gsub

      下面一个例子将匹配chenwu串的行替换成yangliu(注意这里要加引号,不然awk会把它当作变量)

 

[chenwu@localhost unit9-awkIntroduce]$ cat -n grade.txt 
     1  chenwu 05/99 4811 27 
     2  mary   02/22 1231 30
     3  tom    09/15 1182 25
[chenwu@localhost unit9-awkIntroduce]$ awk 'gsub(/chenwu/,"yangliu") {print $0}' grade.txt 
yangliu 05/99 4811 27 

 

     2:index(获取ny串在Bonny的起始位置,注意这里的计数与一般的编程语言不同,这里从1开始计数)

 

[chenwu@localhost unit9-awkIntroduce]$ awk 'BEGIN {print  index("Bonny","ny")}' grade.txt 
4
 

     3:length

 

[chenwu@localhost unit9-awkIntroduce]$ awk '{if($1=="chenwu") print $1,length($1)}' grade.txt
chenwu 6

 

   4:match

       match用来匹配子串(也可以是一个正则表达式 )在父串的位置,如果匹配成功,则返回匹配的位置,否则返回0,例如:

 

[chenwu@localhost unit9-awkIntroduce]$ awk 'BEGIN {print match("ABCD",/C/)}'
3
[chenwu@localhost unit9-awkIntroduce]$ awk 'BEGIN {print match("ABCD",/U/)}'
0
 

   5:split

 

[chenwu@localhost unit9-awkIntroduce]$ awk 'BEGIN {print split("123#45#22",myarray,"#")}'
3
 

   6:substr(s,p[,n])   返回s串中从p开始的后缀部分,n是一个可选参数,表示取多大的长度   

      例如

 

[chenwu@localhost unit9-awkIntroduce]$ awk 'BEGIN {base="I love money"} {print substr(base,3,6)}' grade.txt 
love m
love m
love m

 

   awk的这些函数在和shell的管道符结合在一起的时候,可以发挥很大的作用。例如:

    返回一个目录下所有文件的句点的前缀名称。(不好使)

 

[chenwu@localhost unit9-awkIntroduce]$ ls -l | awk 'BEGIN {if($1!~/^d/) n=index($8,".")} 
{if($1!~/^d/) print n,substr($8,n)}'
0 
0 grade.report
0 grade.txt
[chenwu@localhost unit9-awkIntroduce]$ ls -l
总计 12
-rw-rw-r-- 1 chenwu chenwu   53 06-10 10:16 grade.report
-rw-rw-r-- 1 chenwu chenwu   64 06-11 10:12 grade.txt
drwxrwxr-x 2 chenwu chenwu 4096 06-11 10:28 testDir
 

    这里为什么不好使尼?理由是n在begin里定义了后,之后就不会再变了,稍微改造后,就好使了:

 

[chenwu@localhost unit9-awkIntroduce]$ ls -l | awk '{n=index($8,".")} {if($1!~/^d/) print substr($8,1,n-1)}'

grade
grade
 

    但是这里还是有点瑕疵,你会发现并没有过滤普通目录。grade的上方仍然有输出(空白)

 

   一种较合理的解释是普通目录的确过滤掉了,但是ls -l最上方的总计12  没有过滤到,导致也对它取了次从1到句点.结束的子串,从而打印了空白。

 

 

 

 

 

posted @ 2011-06-11 10:53  老去的JAVA程序员  阅读(175)  评论(0编辑  收藏  举报