您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 市场营销 > Shell 基础十二篇 第四部分
相同。CODE:[sam@chenwysam]$awk'BEGIN{BASELINE=27}{if($6BASELINE)print$0}'grade.txtJ.Lulu06/9948317green92426J.Troll07/994842Brown-31226263.修改数值域取值修改数值域取值修改数值域取值修改数值域取值当在awk中修改任何域时,重要的一点是要记住实际输入文件是不可修改的,修改的只是保存在缓存里的awk复本。awk会在变量NR或NF变量中反映出修改痕迹。为修改数值域,简单的给域标识重赋新值,如:$1=$1+5,会将域1数值加5,但要确保赋值域其子集为数值型。修改M.Tansley的目前级别分域,使其数值从40减为39,使用赋值语句$6=$6-1,当然在实施修改前首先要匹配域名。CODE:[sam@chenwysam]$awk'{if($1==M.Tans){$6=$6-1};print$1,$6,$7}'grade.txtM.Tans3944J.Lulu2426P.Bunny3528J.Troll2626L.Tansl3028CODE:[sam@chenwysam]$awk'{if($1==M.Tans){$6=$6-1;print$1,$6,$7}}'grade.txtM.Tans39444.修改文本域修改文本域修改文本域修改文本域修改文本域即对其重新赋值。需要做的就是赋给一个新的字符串。在J.Troll中加入字母,使其成为J.L.Troll,表达式为$1=J.L.Troll,记住字符串要使用双秒号(),并用圆括号括起整个语法。CODE:[sam@chenwysam]$awk'{if($1==J.Troll)$1=J.L.Troll;print$1}'grade.txtM.TansJ.LuluP.BunnyJ.L.TrollL.Tansl5.只显示修改记录只显示修改记录只显示修改记录只显示修改记录上述例子均是对一个小文件的域进行修改,因此打印出所有记录查看修改部分不成问题,但如果文件很大,记录甚至超过100,打印所有记录只为查看修改部分显然不合情理。在模式后面使用花括号将只打印修改部分。取得模式,再根据模式结果实施操作,可能有些抽象,现举一例,只打印修改部分。注意花括号的位置。CODE:[sam@chenwysam]$awk'{if($1==J.Troll){$1=J.L.Troll;print$1}}'grade.txtJ.L.Troll不知道为什么不知道为什么不知道为什么不知道为什么,,,,我这里多了一个空行我这里多了一个空行我这里多了一个空行我这里多了一个空行????6.创建新的输出域创建新的输出域创建新的输出域创建新的输出域在awk中处理数据时,基于各域进行计算时创建新域是一种好习惯。创建新域要通过其他域赋予新域标识符。如创建一个基于其他域的加法新域{$4=$2+$3},这里假定记录包含3个域,则域4为新建域,保存域2和域3相加结果。在文件grade.txt中创建新域8保存域目前级别分与域最高级别分的减法值。表达式为‘{$8=$7-$6}’,语法首先测试域目前级别分小于域最高级别分。新域因此只打印其值大于零的学生名称及其新域值。在BEGIN部分加入tab键以对齐报告头。CODE:[sam@chenwysam]$awk'BEGIN{printName\tDifference}{if($6$7){$8=$7-$6;print$1,$8}}'grade.txtNameDifferenceM.Tans4J.Lulu2当然可以创建新域,并赋给其更有意义的变量名。例如:CODE:[sam@chenwysam]$awk'BEGIN{printName\tDifference}{if($6$7){diff=$7-$6;print$1,diff}}'grade.txtNameDifferenceM.Tans4J.Lulu27.增加列值增加列值增加列值增加列值为增加列数或进行运行结果统计,使用符号+=。增加的结果赋给符号左边变量值,增加到变量的域在符号右边。例如将$1加入变量total,表达式为total+=$1。列值增加很有用。许多文件都要求统计总数,但输出其统计结果十分繁琐。在awk中这很简单,请看下面的例子。将所有学生的‘目前级别分’加在一起,方法是tot+=$6,tot即为awk浏览的整个文件的域6结果总和。所有记录读完后,在END部分加入一些提示信息及域6总和。不必在awk中显示说明打印所有记录,每一个操作匹配时,这是缺省动作。CODE:[sam@chenwysam]$awk'(tot+=$6);END{printClubstudenttotalpoints:tot}'grade.txtM.Tans5/9948311Green84044J.Lulu06/9948317green92426P.Bunny02/9948Yellow123528J.Troll07/994842Brown-3122626L.Tansl05/994712Brown-2123028Clubstudenttotalpoints:155如果文件很大,你只想打印结果部分而不是所有记录,在语句的外面加上圆括号()即可。CODE:[sam@chenwysam]$awk'{(tot+=$6)};END{printClubstudenttotalpoints:tot}'grade.txtClubstudenttotalpoints:1558.文件长度相加文件长度相加文件长度相加文件长度相加在目录中查看文件时,如果想快速查看所有文件的长度及其总和,但要排除子目录,使用ls-l命令,然后管道输出到awk,awk首先剔除首字符为d(使用正则表达式)的记录,然后将文件长度列相加,并输出每一文件长度及在END部分输出所有文件的长度。本例中,首先用ls-l命令查看一下文件属性。注意第二个文件属性首字符为d,说明它是一个目录,文件长度是第5列,文件名是第9列。如果系统不是这样排列文件名及其长度,应适时加以改变。下面的正则表达式表明必须匹配行首,并排除字符d,表达式为^[^d]。使用此模式打印文件名及其长度,然后将各长度相加放入变量tot中。CODE:[sam@chenwysam]$ls-l|awk'/^[^d]/{print$9\t$5}{tot+=$5}END{printtotalKB:tot}'...................totalKB:174144内置的字符串函数内置的字符串函数内置的字符串函数内置的字符串函数CODE:awk内置字符串函数gsub(r,s)在整个$0中用s替代rgsub(r,s,t)在整个t中用s替代rindex(s,t)返回s中字符串t的第一位置length(s)返回s长度match(s,r)测试s是否包含匹配r的字符串split(s,a,fs)在fs上将s分成序列asprint(fmt,exp)返回经fmt格式化后的expsub(r,s)用$0中最左边最长的子串代替ssubstr(s,p)返回字符串s中从p开始的后缀部分substr(s,p,n)返回字符串s中从p开始长度为n的后缀部分gsub函数函数函数函数有点类似于sed查找和替换。它允许替换一个字符串或字符为另一个字符串或字符,并以正则表达式的形式执行。第一个函数作用于记录$0,第二个gsub函数允许指定目标,然而,如果未指定目标,缺省为$0。index((((s,,,,t))))函数函数函数函数返回目标字符串s中查询字符串t的首位置。length函数返回字符串s字符长度。match函数函数函数函数测试字符串s是否包含一个正则表达式r定义的匹配。split使用域分隔符fs将字符串s划分为指定序列a。sprint函数函数函数函数类似于printf函数(以后涉及),返回基本输出格式fmt的结果字符串exp。sub((((r,,,,s))))函数函数函数函数将用s替代$0中最左边最长的子串,该子串被(r)匹配。sub((((s,,,,p))))返回字符串s在位置p后的后缀。substr(s,p,n)同上,并指定子串长度为n。现在看一看awk中这些字符串函数的功能。1.gsub要在整个记录中替换一个字符串为另一个,使用正则表达式格式,/目标模式/,替换模式/。例如改变学生序号4842到4899:CODE:[root@Linux_chenwyroot]#cd/usr/sam[root@Linux_chenwysam]#awk'gsub(/4842/,4899){print$0}'grade.txtJ.Troll07/994899Brown-3122626CODE:[root@Linux_chenwysam]#awk'gsub(/4842/,4899)'grade.txtJ.Troll07/994899Brown-31226262.index查询字符串s中t出现的第一位置。必须用双引号将字符串括起来。例如返回目标字符串Bunny中ny出现的第一位置,即字符个数。CODE:[root@Linux_chenwysam]#awk'BEGIN{printindex(Bunny,ny)}'grade.txt43.length返回所需字符串长度,例如检验字符串J.Troll返回名字及其长度,即人名构成的字符个数CODE:[root@Linux_chenwysam]#awk'$1==J.Troll{printlength($1)$1}'grade.txt7J.Troll还有一种方法,这里字符串加双引号。CODE:[root@Linux_chenwysam]#awk'BEGIN{printlength(AFEWGOODMEN)}'144.matchmatch测试目标字符串是否包含查找字符的一部分。可以对查找部分使用正则表达式,返回值为成功出现的字符排列数。如果未找到,返回0,第一个例子在ANCD中查找d。因其不存在,所以返回0。第二个例子在ANCD中查找D。因其存在,所以返回ANCD中D出现的首位置字符数。第三个例子在学生J.Lulu中查找u。CODE:[root@Linux_chenwysam]#awk'BEGIN{printmatch(ANCD,/d/)}'0[root@Linux_chenwysam]#awk'BEGIN{printmatch(ANCD,/D/)}'4[root@Linux_chenwysam]#awk'$1==J.Lulu{printmatch($1,u)}'grade.txt45.split使用split返回字符串数组元素个数。工作方式如下:如果有一字符串,包含一指定分隔符-,例如AD2-KP9-JU2-LP-1,将之划分成一个数组。使用split,指定分隔符及数组名。此例中,命令格式为(AD2-KP9-JU2-LP-1,parts_array,-),split然后返回数组下标数,这里结果为4。CODE:[root@Linux_chenwysam]#awk'BEGIN{printsplit(123-456-789,pats_array,-)}'3还有一个例子使用不同的分隔符。CODE:[root@Linux_chenwysam]#awk'BEGIN{printsplit(123#456#789,myarray,#)}'3这个例子中,split返回数组myarray的下标数。数组myarray取值如下:CODE:myarray[1]=123myarray[2]=456myarray[3]=789结尾部分讲述数组概念。6.sub使用sub发现并替换模式的第一次出现位置。字符串STR包含‘popedpopopill’,执行下列sub命令sub(/op/,op,STR)。模式op第一次出现时,进行替换操作,返回结果如下:‘pOPedpopepill’。如:学生J.Troll的记录有两个值一样,“目前级别分”与“最高级别分”。只改变第一个为29,第二个仍为2
本文标题:Shell 基础十二篇 第四部分
链接地址:https://www.777doc.com/doc-4844649 .html