awk命令详解(三)

3.2 条件语句

awk的if语句类似于C语言的if语句,没什么好说的,举一个例子吧:

{ 
    if ( $1 == "foo" ) { 
        if ( $2 == "foo" ) { 
            print "uno" 
        } else { 
            print "one" 
        } 
    } else if ($1 == "bar" ) { 
        print "two" 
    } else { 
        print "three" 
    } 
} 

3.3 循环语句

其时在第1节的最后,我们已经看到了awk的while循环结构,它等同于相应的C语言while循环。awk还有"do...while"循环,它在代码块结尾处对条件求值,还是直接举例吧:

 do...while 示例

{ 
    count=1 
    do { 
        print "I get printed at least once no matter what" 
    } while ( count != 1 ) 
} 

for 循环

也等同于C语言的for循环:

for ( x = 1; x <= 4; x++ ) { 
    print "iteration",x 
} 

break 和 continue

此外,如同C语言一样,awk提供了break、continue来控制awk的循环结构。break语句用于跳出最深层的循环,使循环立即终止,并继续执行循环代码块后面的语句。continue语句使awk立即开始执行下一个循环迭代,而不执行代码块的其余部分。

3.4 数组

在awk中,数组下标通常从1开始,而不是0:

myarray[1]="jim"
myarray[2]=456

awk遇到第一个赋值语句时,它将创建myarray,并将元素myarray[1]设置成"jim"。执行了第二个赋值语句后,数组就有两个元素了。Awk数组不需要连续的数字序列下标(例如,可以定义myarr[1]和myarr[1000],但不定义其它所有元素)

awk可以使用"in"操作来遍历数组中的所有元素,如下所示:

for ( x in myarray ) { 
    print myarray[x] 
} 

但是这个方法有一个缺点——当awk在数组下标之间轮转时,它不会依照任何特定的顺序。那就意味着我们不能知道以上代码的输出是:

jim
456

还是

456
jim

awk数组中还可以使用字符串下标,其实,不管你使用的下标是字符串还是数字,awk在幕后还将其认为是字符串下标。举例如下:

代码一:

myarr["1"]="China" 
print myarr["1"] 

代码二:

myarr["1"]="Mr. Whipple" 
print myarr[1] 

代码三:

myarr["name"]="Mr. Whipple" 
print myarr["name"] 

它们都将打印 "China"!

删除数组元素使用delete,举例如下:

 delete fooarray[1]
另外,如果想要查看是否存在某个特定数组元素,可以使用特殊的"in"布尔运算符,如下所示:

if ( 1 in fooarray ) { 
    print "It's there." 
} else { 
    print "Can't find it." 
} 

4.第三部分:精通

4.1格式化输出

虽然大多数情况下awk的print语句可以完成任务,但有时我们还需要更多。使用两个函数printf()、sprintf(),将能让输出锦上添花。printf()会将格式化字符串打印到stdout,而sprintf()则返回可以赋值给变量的格式化字符串。

从下面例子可以看到,它们几乎与C语言完全相同。

x=1 
b="foo" 
printf("%s got a %d on the last test\n","Jim",83) 
myout=("%s-%d",b,x) 
print myout 

此代码将打印:

Jim got a 83 on the last test
foo-1
4.2 字符串函数

既然awk把所有变量都当作字符串处理,那么字符串处理对awk就显得尤为重要。但要说明一点,awk不能象在其它语言(如 C、C++)中那样将字符串看作是字符数组。例如,如果执行以下代码:

mystring="How are you doing today?" 
print mystring[3] 



将会接收到一个错误,如下所示:

 awk: string.gawk:59: fatal: attempt to use scalar as array


不用担心,awk有许多字符串函数,弥补了这个缺陷。现将常用的字符串函数列举如下:

字符串函数描述
length()返回字符串的长度
index()返回子字符串在另一个字符串中出现的位置
tolower()返回字符串并且将所有字符转换成小写
toupper()返回字符串并且将所有字符转换成大写
substr()返回从字符串中选择的子串
match()返回子字符串在另一个字符串中出现的位置。它与index()的区别在于它并不搜索子串,它搜索的是正则表达式。
sub()替换匹配的第一个字符序列,并返回整个字符串
gsub()替换匹配的全部字符序列,并返回整个字符串
split()分割字符串,并将各部分放到使用整数下标的数组中

length()返回字符串的长度,例子如下:

print length(mystring) 

index()返回子字符串在另一个字符串中出现的位置,如果没有找到该字符串则返回0,例子如下:

print index(mystring,"you") 

tolower()和toupper()返回字符串并且将所有字符分别转换成小写或大写。注意,tolower()和toupper()返回新的字符串,不会修改原来的字符串。例子如下:

print tolower(mystring) 
print toupper(mystring) 

使用substr()可以从字符串中选择子串。以下是substr()的调用方法:

mysub=substr(mystring,startpos,maxlen) 

以下是一个示例:

print substr(mystring,9,3) 

match()与index()非常相似,它与index()的区别在于它并不搜索子串,它搜索的是正则表达式。match()函数将返回匹配的起始位置,如果没有找到匹配,则返回0。此外,match()还将设置两个变量,叫作RSTART和RLENGTH。RSTART包含返回值(第一个匹配的位置),RLENGTH指定它占据的字符跨度(如果没有找到匹配,则返回-1)。通过使用RSTART、RLENGTH、substr()和一个小循环,可以轻松地遍历字符串中的每个匹配。以下是一个match()调用示例:

print match(mystring,/you/), RSTART, RLENGTH 

sub()和gsub()是两个字符串替换函数。sub()的调用方法如下:

sub(regexp,replstring,mystring) 

调用sub()时,它将在mystring中匹配regexp的第一个字符序列,并且用replstring替换该序列。gsub()与sub()的唯一的区别是sub()替换第一个regexp匹配(如果有的话),gsub()则执行全局替换,换出字符串中的所有匹配。举例如下:

sub(/o/,"O",mystring) 
print mystring 
mystring="How are you doing today?" 
gsub(/o/,"O",mystring) 
print mystring 

其输出结果如下:

HOw are you doing today?
HOw are yOu dOing tOday?

split()的功能是分割字符串,并将分割后的各部分放到使用整数下标的数组中。此函数有三个变量,第一个自变量为要分割的原始字符串,第二个自变量为分割后填入的数组名称,第三个变素为用于指示分割的分隔符。split()返回时,它将返回分割的字符串元素的数量。split()将分割的每一个部分赋值给下标从1开始的数组。举例如下:

numelements=split("Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec",mymonths,",") 
print mymonths[1],mymonths[numelements] 

其输出如下:

Jan Dec

最后需要说明一点的是,调用length()、sub()或gsub()时,可以去掉最后一个变量,这样awk将对$0(整个当前行)应用函数调用。例如要打印文件中每一行的长度,使用以下awk脚本:

{ 
    print length() 
} 
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值