awk运用

发布时间:2014-10-22 18:29:45编辑:www.fx114.net 分享查询网我要评论
本篇文章主要介绍了"awk运用",主要涉及到awk运用方面的内容,对于awk运用感兴趣的同学可以参考一下。

1,awk 处理流程 awk的处理流程分三部分,在没有读取任何数据前先执行BEGIN部分,然后进入主循环, 在主循环中读一行并进行处理,处理时先匹配模式部分,若模式部分不匹配将处理下一行。 当处理完所有输入行后,执行END的内容。   若没有BEGIN或END,直接进入主循环执行。   ------------------------------------ ---------------- (1) 在任何数据读入前执行                   BEGIN ------------------------------------ ---------------- (2) 主循环,完成所有的动作                 read a line--> deal with the line                                                             read and deal it  ------------------------------------ ---------------- (3) 文件内容读取完毕后执行                 END ------------------------------------ ----------------   格式形如: awk  'BEGIN{print"start.......\n"} {print $1} END{print "end.....\n"}'   说明:例子文件data内容:   [root@myserver ~]# cat data M.Ta   5/99 48011Green 4 40 44 N.Tans 5/99 58211 Green 840 41 S.Tns 5/99 38311 Green 5 4942 I.Tan 5/99 18321 Green 8 5040 L.Tas 5/99 28311 Green 6 4044 J.Lulu 06/99 48317 green 924 26 P.Bunny 02/99 48 Yellow 1235 28 J.Troll 07/99 4842 Brown-312 26 26   *控制流  if (condition)statement [ else statement ]   while (condition) statement do statement while(condition) for (expr1; expr2; expr3)statement for (var in array)statement break continue delete array[index] delete array exit [ expression ] { statements }   2, awk 支持的正则表达式 c         matches the non-metacharacter c. \c        matches the literal character c. .               匹配任何一个字符,包括换行符 ^             匹配从字符串的开始位置 $              匹配到字符串的尾部   [abc...]     字符列表,匹配[]中的任何一个字符 [^abc...]    非[]列表中的任何字符 r1|r2          可选正则匹配,匹配正则表达式1或表达式2 r1r2          匹配r1和r2都符合的行 r+             匹配符合正则表达式r一次或多次的行 r*             匹配0次或多次r的行 r?        匹配0次或一次正则表达式r的行。 (r)       grouping: matches r. r{n} r{n,} r{n,m}     One ortwo numbers inside braces denote an interval expression.  If there is onenumber in the braces,                  the preceding regular expression r isrepeated n times.  If there  are  two  numbers separated  by  a                  comma,  r is repeated n to m times. If there is one number followed by a comma, then r is repeated at                  least n times.                  Interval expressions are only available ifeither --posix or --re-interval is specified on the command                  line.     3,awk 中的模式匹配 *a w k条件操作符 操作符描述操作符描述 < 小于 > = 大于等于 < = 小于等于 ~ 匹配正则表达式 !~ 不匹配正则表达式 = = 等于 != 不等于   *正则表达式匹配 ~ $1 ~ /regexp/   ~后面接正则表达式,表达式要用/正则表达式/括起来。 在使用正则表达式时,可以有两种形式,使用if或不适用if: awk '$n~/regexp/ {dosomthing}'  datafile 或 awk '{if($n~/regexp/) do somthing}'  datafile    例如: 找出第3列中以48开头的行 [root@myserver ~]# awk'$3~/^48/ {print $0}'  data M.Ta   5/99 48011Green 4 40 44 J.Lulu 06/99 48317 green 924 26 P.Bunny 02/99 48 Yellow 1235 28 J.Troll 07/99 4842 Brown-312 26 26   [root@myserver ~]# awk'{if($3~/^48/) print $0}'  data  M.Ta   5/99 48011Green 4 40 44 J.Lulu 06/99 48317 green 924 26 P.Bunny 02/99 48 Yellow 1235 28 J.Troll 07/99 4842 Brown-312 26 26   *精确匹配 == [root@myserver ~]# awk'$3==48{print $0}'  data P.Bunny 02/99 48 Yellow 1235 28 [root@myserver ~]# awk'{if($3=="48") print $0}'  data P.Bunny 02/99 48 Yellow 1235 28   *不匹配  !~ 找出在第3列中不含11字符串的行 [root@myserver ~]# awk'$3!~/11/{print $0}' data   I.Tan 5/99 18321 Green 8 5040 J.Lulu 06/99 48317 green 924 26 P.Bunny 02/99 48 Yellow 1235 28 J.Troll 07/99 4842 Brown-312 26 26   *不等于 != 找出第3列中不等于48的行 [root@myserver ~]# awk'{if($3!="48") print $0}' data   M.Ta   5/99 48011Green 4 40 44 N.Tans 5/99 58211 Green 840 41 S.Tns 5/99 38311 Green 5 4942 I.Tan 5/99 18321 Green 8 5040 L.Tas 5/99 28311 Green 6 4044 J.Lulu 06/99 48317 green 924 26 J.Troll 07/99 4842 Brown-312 26 26   *大于  > #找出第6列的值>40的行 [zxh@localhost dosh]$ awk'{if($6>40) print $0}' data S.Tns 5/99 38311 Green 5 4942 I.Tan 5/99 18321 Green 8 5040 #或者 [zxh@localhost dosh]$ awk'$6>40{print $0}' data S.Tns 5/99 38311 Green 5 4942 I.Tan 5/99 18321 Green 8 5040   *大小写匹配   ~[aA] *任意单个字符匹配 ~/^...a/ #匹配(1)第1列中第4个字符为r的行 或 (2) 第4列首字母为Y或y的行 [zxh@myserver dosh]$ catdata | awk '{if($1~/^...r/ || $4 ~/^[Yy]/) print $0}' P.Bunny 02/99 48 Yellow 1235 28 J.Troll 07/99 4842 Brown-312 26 26   *正则的或关系~/(reg1|reg2)/ #在用或关系时,注意要用()括起来 [zxh@localhost dosh]$ awk'{if($3~/(^38|^18)/) print $0}' data S.Tns 5/99 38311 Green 5 4942 I.Tan 5/99 18321 Green 8 5040 #上面也是或关系使用的例子   *正则表达中的与关系    ~/reg1/&& ~/reg2/ awk '{if($1=="P.Bunny" && $4=="Yellow") print $0}'grade.txt   *多次匹配 #每次匹配成功时先把结果输出,在进行第2个正则表达式的匹配。 [zxh@localhost dosh]$ awk'$1~/^L/{print $1}; $3~/^28/{print $3}' data L.Tas 28311   * 已28开头11结尾的匹配 awk '$3~/^28.*11$/ {print$0}' data   4, awk常用内置变量 FILENAME     因为a w k可以同时处理许多文件,因此如果访问了这个变量,将告之系统目前正在浏览的实际文件。 FS              用来在a w k中设置域分隔符,与命令行中-F选项功能相同。缺省情况下为空格。 FNR               当前输入文件的记录数 NR                 N record。表示当前输入的总记录数,若是多个文件,它是多个FNR的和。 NF                  N field。表示当前输入记录的域(列)数。 OFS               output field seperator。输出域分割符。默认是空格。 ORS               output record seperator。输入记录(行)分割符,默认是换行符。 ARGC         命令行参数个数 RS                 输入的记录分割符,默认是换行符\n,支持|或&&的支持   注意:在使用时,这些变量不需要加$符号。只有在取这些变量对应的记录值时才需要加。   *NF,NR,FILENAME #计算文件的行数 [zxh@localhost dosh]$ timeawk 'END{print NR}' data 8   说明:#它的性能比起wc -l要慢许多 [zxh@localhost dosh]$ timewc -l data1 4194944 data1   real    0m0.163s user    0m0.120s sys     0m0.041s [zxh@localhost dosh]$ timeawk 'END{print NR}' data1      4194944   real    0m0.525s user    0m0.485s sys     0m0.039s   #打印当前目录(取最后一个域的值) [zxh@localhost dosh]$ echo$PWD | awk -F/ '{print $NF}' dosh   #取文件名 [zxh@localhost dosh]$ echo"/usr/local/sbin/gfmd" | awk -F/ '{print $NF}' gfmd   #cut 也可以做到,但比较笨一些 [zxh@localhost dosh]$ echo"/usr/local/sbin/gfmd" | cut -d/ -f 5 gfmd     5, awk 的操作符 详细说明可以参看:man awk       (...)           组       $              域引用。       ++ --       自增和自减,作为前缀和后缀都可以。       ^              Exponentiation (** mayalso be used, and **= for the assignment operator).       + - !          一元操作符:加,减,非.       * / %        乘,除,取模。       + -           加,减.       space       字符串连接.       < >       <= >=       != ==       关系操作符       ~ !~         正则表达式匹配操作符。.       in             数组成员关系操作符。       &&          逻辑与       ||              逻辑或.       ?:              和C的三元操作符相同       = += -=       *= /= %= ^=  计算操作符.   *使用自定义变量 #注意在引用自定义变量时,不需要添加$符号 #把各个域变量设置成可识别的变量,例如若1列表示名字,那么可以这样做: name=$1 [zxh@localhost dosh]$ awk'{name=$1;score=$3; if($name ~/^L/) print name,score}'  data     L.Tas 28311   *修改域值 # 注意一下记录,$NF的值都变成了30 [zxh@localhost dosh]$ awk'{score=$NF; if(score<30) $NF=30; print score,$0}' data           ... ...   26 J.Lulu 06/99 48317 green9 24 30 28 P.Bunny 02/99 48 Yellow12 35 30 26 J.Troll 07/99 4842Brown-3 12 26 30   *创建新的输出域 #上面的一个例子已经增加了一列,增加一列很容易吧。其实增加列还有另外一种方式。 #以下脚本,我想把最后的三个域的值加起来,然后放到最后一列输出,注意在输出$0时自动把最后一列加进来了。 #若把NF+1改成NF+2,则会自动添加一个空格列,也就是NF+1这一列。 [zxh@localhost dosh]$ awk'{ad=NF+1; $ad=$NF+$(NF-1)+$(NF-2); print $0}' data             M.Ta 5/99 48011 Green 4 4044 88 N.Tans 5/99 58211 Green 840 41 89 S.Tns 5/99 38311 Green 5 4942 96 ... ...   *统计列的值 #统计最后一列的总和 [zxh@localhost dosh]$ awk'{tot+=$NF} END{print "last field total:"tot}' data last field total:291   *文件长度相加 #计算一个目录下,非目录文件的总大小  [root@localhost ~]# ls -l |awk '/^[^d]/{print $5;s+=$5}; END{print "totalsize="s/1024"k"}'   1165 147 35566 5195 13 total size=41.0996k   #计算当前目录非目录文件总大小 [root@localhostlibevbase-0.0.14]# find . -type f -exec ls -l '{}' \; | awk '/^[^d]/{tot+=$5};END{print "size="tot/1024/1024"M"}' size=2.22593M     6, 使用awk中的函数 *内置字符串函数 gsub( r, s)                    在整个$ 0中用s替代r gsub( r, s , t)                在整个t中用s替代r index(s , t)                 返回s中字符串t的第一位置,若没有找到返回0 length(s)                  返回s长度 match(s , r)                测试s是否包含匹配r的字符串 split(s , a , fs)            在fs上将s分成序列a sprint(fmt , exp)      返回经f m t格式化后的e x p sub(r, s )                        用$ 0中最左边最长的子串代替s substr(s , p)               返回字符串s中从p开始的后缀部分 substr(s , p , n)          返回字符串s中从p开始长度为n的后缀部分   说明:详细使用说明,请man awk,搜索gsub等。   *字符串替换 注意:字符串替换要加双引号: gsub(/oldstring/,"newstring",$1) #在整个记录中把383替换成888 [zxh@myserver dosh]$ catdata | awk 'gsub(/383/,888){print $0}'  S.Tns 5/99 88811 Green 5 4942   *在某一列中替换 #把第1列中的字符串Lulu替换成字符串hover,注意加双引号 [zxh@myserver dosh]$ catdata | awk 'gsub(/Lulu/,"hover",$1){print $0}'  J.hover 06/99 48317 green 924 26   *替换字符串第一次出现的位置 sub # 使用s u b发现并替换模式的第一次出现位置。和gsub相似,但只替换第一次出现的字符。 # sub(r, s [, t])   r是正则表达式;s是是要替换的字符串。t是域号,若没有指定,则是$0 [zxh@myserver dosh]$ catdata | awk '$0~/^L/{sub(44,55);print $0}' L.Tas 5/99 28311 Green 6 4055     *查找字符串 #查找第一列中包含字符串"Lulu"的行 [zxh@myserver dosh]$ catdata | awk 'index($1,"Lulu"){print $0}' J.Lulu 06/99 48317 green 924 26   *分割字符串split [zxh@myserver dosh]$ catdata | awk '$1~/J\.L/{split($0,arr," ")} END {print arr[3]}' 48317   #另外一个例子 [root@Linux_chenwy sam]#awk 'BEGIN {print split("123#456#789",myarray,"#")}'   *输出字符串长度length [zxh@myserver dosh]$ catdata | awk '$0~/^L/{print length($1),$1}' 5 L.Tas     *字符串切割  # substr(s, i [, n])  # Returns the at mostn-character substring of s starting at i.  If n is omitted, the rest of sis used #打印第2个域,从"/"开始的字符串其余部分 [zxh@myserver dosh]$ catdata | awk '$0~/^L/{sub(44,55);print substr($2,index($2,"/"))}' /99     7, 使用awk脚本文件 可以将a w k脚本写入一个文件再执行它。命令不必很长(尽管这是写入一个脚本文件的主 要原因),甚至可以接受一行命令。 使用awk脚本文件有以下优点: (1)这样可以保存a wk命令,以使不必每次使用时都需要重新输入。 (2)使用文件的另一个好处是可以增加注释,以便于理解脚本的真正用途和功能。   *基本格式 第一行必须是:  !/bin/awk -f 表示awk命令从文件中读取命令行。   *例1 [zxh@localhost dosh]$ catdo.awk  #!/usr/bin/awk -f # myfirst.awk  #  # BEGIN {        print "--------------start-----------" }   {        if ($5>10)                print "<10 "$5        else                print ">10 "$5 }   END {        print "-------------end--------------" }


上一篇:
下一篇:友好用户界面--界面设计技巧

相关文章

关键词: awk运用

相关评论

本站评论功能暂时取消,后续此功能例行通知。

一、不得利用本站危害国家安全、泄露国家秘密,不得侵犯国家社会集体的和公民的合法权益,不得利用本站制作、复制和传播不法有害信息!

二、互相尊重,对自己的言论和行为负责。

好贷网好贷款