您的位置:首页 > 运维架构 > Shell

awk内置变量2-2

2012-04-27 16:41 169 查看
7. 增加列值

为增加 列数或进行运行结果统计,使用符号+ =。增 加的结果赋给符号左边变量值,增加到变量的域在符号右边。例如将$ 1加入变量t o t a l,表达式为t o t a l + = $ 1。列值增加很有用。许多文件都要 求统计总数,但输出其统计结果十分繁琐。在a w k中这很简单,请看下面的例子。

将所有 学生的‘目前级别分’加在一起,方法是t o t + = $ 6,t o t即为a w k浏览的整个文件的域6结果总和。所有记录读完后,在E N D部分加入一些提示信息及域6总和。不必在a w k中显示说明打印所有记录,每一个操作匹配时,这是缺省动作。

[Copy to clipboard] [ - ]
CODE:
[sam@chenwy sam]$ awk '(tot+=$6); END{print "Club student total points :" tot}'

grade.txt

M.Tans 5/99 48311 Green 8 40 44

J.Lulu 06/99 48317 green 9 24 26

P.Bunny 02/99 48 Yellow 12 35 28

J.Troll 07/99 4842 Brown-3 12 26 26

L.Tansl 05/99 4712 Brown-2 12 30 28

Club student total points :155

如果文 件很大,你只想打印结果部分而不是所有记录,在语句的外面加上圆括号()即可。
[Copy to clipboard] [ - ]
CODE:
[sam@chenwy sam]$ awk '{(tot+=$6)}; END{print "Club student total points :" tot}' grade.txt

Club student total points :155

8. 文件长度相加

在目录 中查看文件时,如果想快速查看所有文件的长度及其总和,但要排除子目录,使用ls -l命令,然后管道输出到a w k,a w k首先剔除首字符为d(使用正则表达式)的记录,然后将文件长度列相加,并输出每一文件长度及在E N D部分输出所有文件的长度。

本例 中,首先用ls -l命令查看一下文件属性。注意第二个文件属性首字符为d,说明它是一个目录,文件长度是第5列,文件名是第9列。如果系统不是这样排列文件名及其长度,应适时加以改变。

下面的 正则表达式表明必须匹配行首,并排除字符d,表达式为^ [ ^ d ]。

使用此 模式打印文件名及其长度,然后将各长度相加放入变量t o t中。
[Copy to clipboard] [ - ]
CODE:
[sam@chenwy sam]$ ls -l | awk '/^[^d]/ {print $9"\t"$5} {tot+=$5} END {print "total KB:" tot}'

...................

total KB:174144

内置的字符串函数
[Copy to clipboard] [ - ]
CODE:
awk内置字符串函数

g s u b ( r, s ) 在整个$ 0中用s替代r

g s u b ( r, s , t ) 在整个t中用s替代r

i n d e x ( s , t ) 返回s中字符串t的第一位置

l e n g t h ( s ) 返回s长度

m a t c h ( s , r ) 测试s是否包含匹配r的字符串

s p l i t ( s , a , f s ) 在f s上将s分成序列a

s p r i n t ( f m t , e x p ) 返回经f m t格式化后的e x p

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

s u b s t r ( s , p ) 返回字符串s中从p开始的后缀部分

s u b s t r ( s , p , n ) 返回字符串s中从p开始长度为n的后缀部分

g s u b函数有点类似于s e d查找和替换。它允许替换一个字符串 或字符为另一个字符串或字符,并以正则表达式的形式执行。第一个函数作用于记录$ 0,第二个g s u b函数允许指定目标,然而,如果未指定目标,缺省为$ 0。

i n d e xst)函数返回目标字符串s中查询字符串t的首位置。l e n g t h函数返回字符串s字符长度。

m a t c h函数测试字符串s是否包含一个正则表达式r定义的匹配。s p l i t使用域分隔符f s将字符串s划分为指定序列a。

s p r i n t函数类似于p r i n t f函数(以后涉及),返回基本输出 格式f m t的结果字符串e x p。

s u brs)函数将用s替代$ 0中最左边最长的子串,该子串被( r)匹配。

s u bsp返回字符串s在位置p后的后缀。s u b s t r(s,p,n)同上,并指定子串长度为n。

现在看 一看a w k中这些字符串函数的功能。

1. gsub

要在整 个记录中替换一个字符串为另一个,使用正则表达式格式, /目标模式/,替换模式/。例如改变学生序号4 8 4 2到4 8 9 9:
[Copy to clipboard] [ - ]
CODE:
[root@Linux_chenwy root]# cd /usr/sam

[root@Linux_chenwy sam]# awk 'gsub(/4842/,4899){print $0}' grade.txt

J.Troll 07/99 4899 Brown-3 12 26 26

[Copy to clipboard] [ - ]
CODE:
[root@Linux_chenwy sam]# awk 'gsub(/4842/,4899)' grade.txt

J.Troll 07/99 4899 Brown-3 12 26 26

2. index

查询字 符串s中t出现的第一位置。必须用双引号将字符串括起来。例如返回目标字符串B u n n y中n y出现 的第一位置,即字符个数。
[Copy to clipboard] [ - ]
CODE:
[root@Linux_chenwy sam]# awk 'BEGIN {print index("Bunny","ny")}' grade.txt

4

3. length

返回所 需字符串长度,例如检验字符串J . Tr o l l返回名字及其长度,即人名构成的字符个数
[Copy to clipboard] [ - ]
CODE:
[root@Linux_chenwy sam]# awk '$1=="J.Troll" {print length($1)" "$1}' grade.txt

7 J.Troll

还有一 种方法,这里字符串加双引号。
[Copy to clipboard] [ - ]
CODE:
[root@Linux_chenwy sam]# awk 'BEGIN{print length("A FEW GOOD MEN")}'

14

4. match

m a t c h测试目标字符串是否包含查找字符的一部分。可以对查找部分使用正则表达式,返回值为成功出现的字符排列数。如果未找到,返回0,第一个例子在A N C D中查找d。因其不存在,所以返回0。第二个例子在A N C D中查找D。因其存在,所以返回A N C D中D出现的首位置字符数。第三个例子在学生J . L u l u中查找u。
[Copy to clipboard] [ - ]
CODE:
[root@Linux_chenwy sam]# awk 'BEGIN{print match("ANCD",/d/)}'

0

[root@Linux_chenwy sam]# awk 'BEGIN{print match("ANCD",/D/)}'

4

[root@Linux_chenwy sam]# awk '$1=="J.Lulu" {print match($1,"u")}' grade.txt

4

5. split

使用s p l i t返回字符串数组元素个数。工作方式如下:如果有一字符串,包含一指定分隔符- ,例如A D2 - K P 9 - J U 2 - L P - 1,将之划分成一个数组。使用s p l i t,指定分隔符及数组名。此例中,命令格式为( " A D 2 - K P 9 - J U 2 - L P - 1 ",p a r t s _ a r r a y," - "),s p l i t然后返回数组下标数,这里结果为4。
[Copy to clipboard] [ - ]
CODE:
[root@Linux_chenwy sam]# awk 'BEGIN {print split("123-456-789",pats_array,"-")}'3

还有一 个例子使用不同的分隔符。
[Copy to clipboard] [ - ]
CODE:
[root@Linux_chenwy sam]# awk 'BEGIN {print split("123#456#789",myarray,"#")}' 3

这个例 子中,s p l i t返回数组m y a r r a y的下标数。数组m y a r r a y取值如下:
[Copy to clipboard] [ - ]
CODE:
myarray[1]=123

myarray[2]=456

myarray[3]=789

结尾部 分讲述数组概念。

6. sub

使用s u b发现并替换模式的第一次出现位置。字符串S T R包 含‘poped popo pill’,执行下列s u b命 令s u b(/ o p /," o p ",S T R)。 模式o p第一 次出现时,进行替换操作,返回结果如下:‘pO Ped pope pill’。

如:学 生J . Tr o l l的记录有两个值一样,“目前级别分”与“最高级别分”。只改变第一个为2 9,第二个仍为2 4不动,操作命令为s u b(/ 2 6 /," 2 9 ",$ 0),只替换第一个出现2 4的位置。注意J . Tr o l l记录需存在。
[Copy to clipboard] [ - ]
CODE:
[root@Linux_chenwy sam]# awk '$1=="J.Troll" sub(/26/,"29",$0)' grade.txt

M.Tans 5/99 48311 Green 8 40 44

J.Lulu 06/99 48317 green 9 24 29

P.Bunny 02/99 48 Yellow 12 35 28

J.Troll 07/99 4842 Brown-3 12 29 26

L.Tansl 05/99 4712 Brown-2 12 30 28

7. substr

s u b s t r是一个很有用的函数。它按照起始位置及长度返回字符串的一部分。例子如下:
[Copy to clipboard] [ - ]
CODE:
[root@Linux_chenwy sam]# awk '$1=="L.Tansl" {print substr($1,1,3)}' grade.txt

L.T

上面例 子中,指定在域1的第一个字符开始,返回其前面5个字符。

如果给 定长度值远大于字符串长度, a w k将从起始位置返回所有字符,要抽取L Ta n s l - e y的姓,只需从第3个字符开始返回长度为7。可以输入长度9 9,a w k返回结果相同。
[Copy to clipboard] [ - ]
CODE:
[root@Linux_chenwy sam]# awk '$1=="L.Tansl" {print substr($1,1,99)}' grade.txt

L.Tansl

s u b s t r的另一种形式是返回字符串后缀或指定位置后面字符。这里需要给出指定字符串及其返回字串的起始位置。例如,从文本文件中抽取姓氏,需操作 域1,并从第三个字符开始:
[Copy to clipboard] [ - ]
CODE:
[root@Linux_chenwy sam]# awk '{print substr($1,3)}' grade.txt

Tans

Lulu

Bunny

Troll

Tansl

还有一 个例子,在B E G I N部分定义字符串,在E N D部分返回从第t个字符开始抽取的子串。
[Copy to clipboard] [ - ]
CODE:
[root@Linux_chenwy sam]# awk 'BEGIN{STR="A FEW GOOD MEN"}END{print substr(STR,7)}' grade.txt

GOOD MEN

8. s h e l l中向a w k传入字符串

a w k脚本大多只有一行,其中很少是字符串表示的。大多要求在一行内完成a w k脚本,这一点通过将变量传入a w k命令行会变得很容易。现就其基本原理讲

述一些 例子。

使用管 道将字符串s t a n d - b y传入a w k,返回其长度。
[Copy to clipboard] [ - ]
CODE:
[root@Linux_chenwy sam]# echo "Stand-by" | awk '{print length($0)}'

8

设置文 件名为一变量,管道输出到a w k,返回不带扩展名的文件名。
[Copy to clipboard] [ - ]
CODE:
[root@Linux_chenwy sam]# STR="mydoc.txt"

[root@Linux_chenwy sam]# echo $STR|awk '{print substr($STR,1,5)}'

mydoc

设置文 件名为一变量,管道输出到a w k,只返回其扩展名。
[Copy to clipboard] [ - ]
CODE:
[root@Linux_chenwy sam]# STR="mydoc.txt"

[root@Linux_chenwy sam]# echo $STR|awk '{print substr($STR,7)}'

txt

字 符串屏蔽序列

使用字 符串或正则表达式时,有时需要在输出中加入一新行或查询一元字符。

打印一 新行时,(新行为字符\ n),给出其屏蔽序列,以不失其特殊含义,用法为在字符串前加入反斜线。例如使用\ n强迫打印一新行。

如果使 用正则表达式,查询花括号( { }), 在字符前加反斜线,如/ \ { /,将在a w k中 失掉其特殊含义。
[Copy to clipboard] [ - ]
CODE:
awk中使用的屏蔽序列

\ b 退 格键

\ t t a b键

\ f 走 纸换页

\ d d d 八进制值

\ n 新 行

\ c 任 意其他特殊字符,例如\ \为反 斜线符号

\ r 回 车键

使用上 述符号,打印May Day,中间夹t a b键,后跟两个新行,再打印May Day,但这次使用八进制数1 0 4、1 4 1、1 7 1、分别代表D、a、y。
[Copy to clipboard] [ - ]
CODE:
[root@chenwy sam]# awk 'BEGIN {print"\n\May\tDay\n\nMay\t\104\141\171"}'

May Day

May Day

注意,\ 1 0 4为D的八进制A S C I I码,\ 1 4 1为a的八进制A S C I I码,等等。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  shell