我们拒绝平庸,拒绝随波逐流,拒绝墨守成规,让梦想不再流浪。

DNS和awk

上一篇 / 下一篇  2014-05-28 11:12:13 / 个人分类:总结

51Testing软件测试网/[!m0t0\~r

此贴主要介绍小侠在COP亚马逊环境配置DNS的经验,如果哪位大神有更好的解决方法,欢迎回贴指导:)

| lzMnk&Mwc051Testing软件测试网8\]}4j\ai%?

DNS 是计算机域名系统或域名解析服务器(Domain Name System 或Domain Name Service) 的缩写,它是由解析器以及域名服务器组成的。域名服务器是指保存有该网络中所有主机的域名和对应IP地址,并具有将域名转换为IP地址功能的服务器。51Testing软件测试网o ]-k,nG |

5q1z5N#M4Mq+A*YUM0亚马逊环境域名www.sdpcop.com为通过万网申请的付费域名。配置了泛域解析,即所有.sdpcop.com后缀的子域名都能解析到亚马逊环境的服务器中,例如a.sdpcop.com,b.sdpcop.com或a.b.sdpcop.com都能解析到亚马逊环境同一台服务器中。51Testing软件测试网L/?7s.[&Z"A

51Testing软件测试网o IIx%S+n.r

引出问题

3A1T|1c7oxO'|051Testing软件测试网v4S h({q*I*f

COP环境分为商用域和测试域,分别部署在不同的服务器中,且需要使用的子域名规则不一样。商用域涉及使用的子域名规则为xxx.sdpcop.com,测试域涉及使用的子域名规则为xxx.test.sdpcop.com。51Testing软件测试网XXM j4D!ODw h

4]#PR4zP)f0在没有使用负载均衡设备情况下,申请的域名只能解析到一台服务器对应IP地址,即所有xxx.sdpcop.com子域名(包括xxx.test.sdpcop.com,此时xxx.test也被认为是xxx)都解析到商用域服务器。当调用测试域和商用域能力时,不能同时满足域名的自动解析到不同的服务器中的要求。

!Jr)Kh.Dj;[i0

'q:Qa1otwt"O0解决思路

2M_H1A|x^3`8R0

}M O5D6}`Io0将商用域服务器设置为亚马逊环境首选DNS服务器,专门用于解析xxx.test.sdpcop.com类子域名,将此类子域名映射至测试域服务器IP地址。即xxx.test.sdpcop.com子域名可解析至测试域服务器,剩余的xxx.sdpcop.com子域名保持默认映射关系,解析至商用域服务器。

}2E Euz J0Arlc [3N/B0

\W!L~8DjU3u N0操作方法

A$rlp-{_0

V)I?`$Gq2[ v&p0                                步骤 1     将商用域服务器配置为DNS服务器。51Testing软件测试网1b(E7o%d,N$w

V {2xj*h:O3e~0a.          以root用户登录商用域服务器。51Testing软件测试网5~+j(nZ"i%i

51Testing软件测试网LR;ApH _?K

b.         安装bind组件包。

{p%\sW3u3s051Testing软件测试网XH,w M+Q;F

配置DNS服务前,需要安装bind组件包,可通过yast工具进行安装。

p+AZ3O ~!C0T [051Testing软件测试网A? V~e7i4t

c.          在/var/lib/named目录下新增域名解析文件,包括正向解析文件与反向解析文件。

Uii e _'|d0

%Z v8k c!~)^ m'~y[0# vi test.sdpcop.com.zone          --增加正向解析文件

_-kx7g4l6M9o0

u!Sr `;Av0$TTL 1W

vT#tBp[ f$F5[5X0

9h6nqu}TlG0@               IN SOA  test.sdpcop.com   root (51Testing软件测试网.P3N2o i,wm)K#[7`

,nZJ u1_g8u$c0                                42              ; serial (d. adams)

6o@+w zp3Z!B3Iv:H0

QQ})d/M5l]-Mb]X0                                2D              ; refresh

q)l9]6m{e.}051Testing软件测试网Sb*t.h jb$o

                                4H              ; retry

$iK"n_ga CL0

a,p:~$b [ o0                                6W              ; expiry51Testing软件测试网'JE7PC+G

51Testing软件测试网W9c-o$z g L:g

                                1W )            ; minimum51Testing软件测试网$}1\;U.x f"Q

y-p]0F"X'W6P V n6@0 51Testing软件测试网w%G%}(I,?A,zm\

b[!` UXLY0                IN NS           test.sdpcop.com.

] zq4l`u N:lv051Testing软件测试网k,g!S[O7I

                IN A           10.80.82.5651Testing软件测试网 E3re_9D7i

51Testing软件测试网F^Kg%m+WPI~

dns            IN A           10.80.82.56

*f l m `(k051Testing软件测试网u?"R:W1~+Mr

*               IN A           10.114.153.23051Testing软件测试网^!wf| hi3h:~ ul

Xh@Wt0n;QN(Z(A6K6P0test.sdpcop.com为设置的域名51Testing软件测试网8D hQo5SX

C5p uON0*表示对解析test.sdpcop.com所有子域名51Testing软件测试网%QP5J)So|y

3l|)a6S,j9A.]010.80.82.56为商用域服务器IP地址

-yX;a@{051Testing软件测试网y-i.yi(Wfd

10.114.153.230为测试域服务器IP地址

;[(X"B(f/B_1s051Testing软件测试网3Wd?miMC/^ a:T

 51Testing软件测试网4fx6w}D5d9vUsC_

qn#A$d"q|N8kt0# vi 10.80.82.zone     --增加反向解析文件

fo!L Fs,i0

Ab%UaGW p0P(|0$TTL 1W

C j5C3^~;I"RE2f051Testing软件测试网8P0i'\:H_:GD"@8q9h

@               IN SOA       test.sdpcop.com.   root (

q&uu^;hB$T2E;mq0

b"h;u3i3w@7k.HJy0                                42              ; serial (d. adams)51Testing软件测试网1My\e"p7EA

51Testing软件测试网 TRssfzL8H

                                2D              ; refresh51Testing软件测试网-xHu/@&bA`,l$``H

51Testing软件测试网t3q6TK,pk

                                4H              ; retry51Testing软件测试网 `,hN`w9uL b

#d2h }%V2r"h3C0                                6W              ; expiry51Testing软件测试网;^K*U+L*?l

51Testing软件测试网,dCn5L7F p'xg@G1h

                                1W )            ; minimum

2mRw3S"Z\/C0

!k*V}A:f?_B0 

C:_kH?1dCB Re]051Testing软件测试网1N_/f:s]

                  IN NS           test.sdpcop.com.

B)sU3t+gL*x-\(TD7{O0

J&_*A9@(Y }Pf#|056                IN PTR          test.sdpcop.com.51Testing软件测试网rC3Y.i z

sxh8AR0d.         配置/etc/named.conf文件,将需要解析的域名文件信息添加至此配置文件中。51Testing软件测试网XtI#O\9x|:~

51Testing软件测试网1bf;YP A R

添加如下信息:

4}V;\j3u^;M0

/Wz,CA-t y*sU&@0zone "test.sdpcop.com" in {

j e*M U"y(tI051Testing软件测试网 r]&_nt:VY/L

        type master;51Testing软件测试网7\[:f'fA&XG3w-`

A'e`$u%QRx,L0        file "test.sdpcop.com.zone";

V5`J]7Y})A051Testing软件测试网 O w pjI{f$O-\

};

,i7|4A%m rN&T,l+J;b"s0

!eQ|LrS0zQb0zone "82.80.10.in-addr.arpa" in {51Testing软件测试网#By$BJr6[)R j

51Testing软件测试网2v$j wQx/sD rr&?

        type master;

g NI9qR X2A9{E0

8nK@6|](a0        file "10.80.82.zone";

*Km sW*AD0TS^ |eT0

5z|-f"HT"PZ'n6?Z0};51Testing软件测试网~u9\k0m`x

1u:Q-g(])gA#r0e.          配置/etc/resolv.conf文件,将此服务器设置为首选DNS服务器。51Testing软件测试网s&X9M'}'C

N eU!kl#D^\@5Xr0在文件中添加如下信息:

^ Scg'@{S SKo0

0I C$ls\:nDfqsp0nameserver 10.80.82.5651Testing软件测试网1L3\8nqY!C8a?\p

R0P5a~i0f.          执行rcnamed restart命令重启域名服务。

"n\q,@T051Testing软件测试网9W$N,n bs

                                步骤 2     设置测试域服务器的首选DNS服务器为商用域服务器。51Testing软件测试网'a:E`+I(s3^ z

51Testing软件测试网pUYwS

a.          以root用户登录测试域服务器。

a5A#pS/p)P8t051Testing软件测试网?S F!OX+s_+w"aS

b.         配置/etc/resolv.conf文件,将商用域服务器作为此服务器的首选DNS服务器。

a?8ff-B Z3v_0

Q%K*dpG-\;{0d_-E0在文件中添加如下信息:

R8K'tLV0

ELu;d:Mx6F*KP#X0nameserver 10.80.82.5651Testing软件测试网8F#izX` |

DuY!^3ux"kXFS0c.          执行rcnamed restart命令重启域名服务。

oZ ot-WB}0

:gv2a2t8u0                                步骤 3     在商用域服务器中执行nslookup命令测试域名解析是否正确。51Testing软件测试网v|L}v(c

Os LJ3^O/S HfH0# nslookup a.sdpcop.com           商用子域名

4uq:C#rf+b!mO051Testing软件测试网r!S C3[1C n)t

server:         10.80.82.56

(lgI5N"v%xq0

2Dy8~ W W%k{0Address:    10.80.82.56#53 

mV] nQ1V sU,]2i0

"A_r1D O!z2R%_qT0 

g6|.Ky:KnM3C8m:h eN051Testing软件测试网;i i(Z)HGUl

Name:       a.sdpcop.com

V:g&e0q*s9A9n/M$]Q0

#{!U+RpF1d7{-x'Fa)k0Address:        10.80.82.56

1X_J Bx#[Zt3I051Testing软件测试网n$L7M7_~G;s*cn7[

下面一行Address的IP地址表示域名解析后的IP地址,子域名解析到商用域服务器IP地址,表示解析正确。

vv:@0TS%N0c051Testing软件测试网IB8L7k4NHk@

# nsklooup a.test.sdpcop.com     测试子域名51Testing软件测试网f0BSLW:~S9BF

5zB1Bt'WV aw'?4P0server:         10.80.82.56

A9q+QQ(N051Testing软件测试网,Q/d4BH9v2`-C,Y"MD6x(B

Address:    10.80.82.56#53 51Testing软件测试网!l%o%~&~7Ag

3AQ^Y4il!u&W0 51Testing软件测试网dgH t.s/M5f

51Testing软件测试网#}|Cf'nOT

Name:       a.test.sdpcop.com

?E O(d @{q PI0

'Qw%{V/?6xD7@+_h0Address:        10.114.153.23051Testing软件测试网:T.c2b| au5u6yP

51Testing软件测试网jo_5w(]g-{S`/z

下面一行Address的IP地址表示域名解析后的IP地址,子域名解析到测试域服务器IP地址,表示解析正确。

8vf.e/gW/W&y0\,X051Testing软件测试网$ouT ?b }

---结束51Testing软件测试网 o@,I V,Y8Z|;t r

Io+p*k1c/L JB0

q&X9n ? fM(v4wpb0 

3H3g#i"zf&w051Testing软件测试网|0n _+s9^:j im\#?

q8Ra'_5l:mA1`0

4t7xq9i4A0 51Testing软件测试网|-bp7@*A1W(X`

&lKx'z`!t0awk速成指南

*G*u`5Z\8wQ3I051Testing软件测试网 R(k U*Vq9`5G;v

(51Testing软件测试网pZSg!PmZd?

C/MZM*f;p6]P0目  录Catalog

.t8W6{}0g\2zL051Testing软件测试网dC+R I5\S3T!}

1    前言... 5

?v1G?M`e051Testing软件测试网9lY/i n E

2    第一部分:入门... 551Testing软件测试网S0E"p SJ

51Testing软件测试网#a.m-c uYY

2.1      第一个awk程序... 551Testing软件测试网"?:`(q-^)A2z

51Testing软件测试网 z.T X8Y4Q` zj

2.2      常用变量... 551Testing软件测试网p2kZ W6J

51Testing软件测试网:A [mn^}+X|

2.3      表达式和运算符... 7

.v0] F z6S,O051Testing软件测试网 ^Ksq6oR2t J^1g

2.4      字符串化变量... 851Testing软件测试网:`|7vp(h-mT

~#J[+`"yq/W p03    第二部分:提高... 8

:@3oZF#o@r0

*O/\^&CG&}/c` l!O/C]03.1      处理多行... 8

Zr:y.G,W051Testing软件测试网-@3^rWuvReB

3.2      条件语句... 1051Testing软件测试网hp#La]7uu;l

B#rFV&Q5l03.3      循环语句... 1051Testing软件测试网CN#u*cCs+q9PH

51Testing软件测试网kgu]K CzS

3.4      数组... 1151Testing软件测试网d5bLR(zq'[o&@%d

51Testing软件测试网#M,OLV#Rs;}S

4    第三部分:精通... 1251Testing软件测试网pV7M5\*S2I%b.n

7U"u yz*y)w04.1      格式化输出... 12

@\T3@Flj}0

+fv kt3U,bO04.2      字符串函数... 12

-WF`G6v,G0

h F ``RM0| ^0 51Testing软件测试网\0S;k7CG

mPOGD051Testing软件测试网!P{ E-n5C5X%T@B
 51Testing软件测试网Q0Xi%m6R6w2cqD^W*J

xDd*nF0R,Q/Lw0awk速成指南

\3o"O$wJ0vh7g051Testing软件测试网^;y#T,to#DDi D;O

关键词Key words:awk,编程,语言,Unix

sc5v g wM051Testing软件测试网 H5m6E@!M7H)?"Y s

摘    要Abstract:awk是一种非常好的编程语言,适用于文本处理和报表生成,在我们的日常测试工作中非常有用。本文分三个部分由浅入深讲述了使用awk语言编程的方法与技巧,通过大量的例子,使大家快速上手,掌握awk语言的精髓。

j;}N`.^S,Z051Testing软件测试网Y]'Q"Q/db L

缩略语清单List of abbreviations:

L!T/|?m#~c051Testing软件测试网V c+[6dH~M

Abbreviations缩略语51Testing软件测试网N_Br7I/~Z

`mA%p"a5C0Full spelling 英文全名51Testing软件测试网0l7GJG1X0] M

51Testing软件测试网j VS!k|,G

Chinese explanation 中文解释51Testing软件测试网9R3V1Lh}Pu7r}

bXkl8qD4a,u7[M0 

4c!gK%i5Ne)F|0

(w3g!H*VA#ou {,M._0 

)p:I}RD,_3w051Testing软件测试网,T'v-I R JKD4D+Pr ]#i

 

A#q1Hr G"H w051Testing软件测试网7PG$[Fk%A:A6|

 

3i4F8`1Zy0d&V0

kIn+f!A:vt9]0 51Testing软件测试网M1@2f,\0n'ch

4xtV0U k/b.z0 51Testing软件测试网~?rT8G0x,C^-})MC:D

cK I%`;N$h0 51Testing软件测试网t gI}"vL5W

|*\ r I0Dz0 51Testing软件测试网!@;u6Q4d+Ve Jy

2J.?5n7w&P{^0 51Testing软件测试网*T'G;xb0LR6C

3SX Y|o&Ut0 51Testing软件测试网Y4c2N'AGz9N

51Testing软件测试网._LYn)T!m

 51Testing软件测试网 @'Y6Kq(F){G7l8^

51Testing软件测试网"v |/w6uA&M\-|

 

V\D"Lk+O"]f0

(AA p n1j8FpB0 51Testing软件测试网O%c3nF1[;[4E y,X

51Testing软件测试网 Gk1b5t4d O/h(G

 

'd.}K(VS0Y,}0

P$M/vB,`&pi0
.PO.S;I3my*E0 

S"ak{V!^9x7k01          前言

f$ves[*I5_q0awk是Unix环境下一种非常好的语言,适合于文本处理和报表生成,它还有许多精心设计的特性,允许进行特殊技巧程序设计。对于短消息来说,比如处理话单文件,使用awk就非常方便,鉴于测试组大部分人对awk并不熟悉,因此仅以本文作一个提纲挈领的介绍,希望对初学者迅速掌握awk有所帮助。51Testing软件测试网,Sejyd$B wQ+Y3t

2          第一部分:入门 2.1    第一个awk程序

w2r!|#UQ3O)J0所有的编程书籍都是通过一个“Hello world!”简单程序入门,作为借鉴,本文也采用此方法带大家入门。现在,在当前目录下建立一个文本文件hello.txt,内容如下:

t:o;bI;_ \z \0

rtam6]0M4},rW051Testing软件测试网9pM!a z*aP0t"_:kh

Hello world!

g*Xy,Iyp-fN4b6o051Testing软件测试网v5^(I%i} zE

J G9TG7k#g+L"V051Testing软件测试网$VzT5F x~)J)C;T

在命令行中输入以下命令:

Ws`/s/J1G,T0

,o\8u YvB uw051Testing软件测试网 P/o3xTAd/{)i

$ awk '{ print }' hello.txt

*sp1[]CX({051Testing软件测试网b0z i4TM/q

51Testing软件测试网b NcPoOYT:[

51Testing软件测试网 `3yQv7N#E:V

执行后hello.txt文件的内容显示在屏幕上。编写并且执行awk程序的方法很简单,如上所示,花括号内的是程序代码,后面的hello.txt为指定的输入文件。awk是一种行处理程序,执行awk时,它依次对输入文件中的每一行执行花括号中的代码,如上面的例子,就是对hello.txt中的每一行执行print命令。所有输出都发送到stdout,最后在屏幕上显示的结果为“Hello world!”。51Testing软件测试网6|!md)]6U_ l3z

4kPUR0g0上面的例子是将脚本作为命令行自变量传递给awk,我们也可以把脚本写入一个外部文件,然后通过-f选项向awk传递这个脚本文件。例如编写脚本文件hello.ask如下:

{&\8z&Oz:nQM051Testing软件测试网:r4b6P"AkdsP H6S4k

-L6z'`+O&[,q1U0{ print }

H mlz.C&e&x%f051Testing软件测试网bvTKu|

51Testing软件测试网_ A/PZqqy3Z#Q

51Testing软件测试网y%k#i6`X M

然后通过如下方式执行:51Testing软件测试网 ge.Ls4tx7_

*Yt|)v x0

A*p:IFO"]r7y!cn nl0$ awk -f hello.awk hello.txt

L0b#{W RN7iM:Ay051Testing软件测试网oD/A1MM

51Testing软件测试网0A V.b2p~ _5?A

m7hn-fM i9_!m9Sh0这种编写独立脚本文件的方式应用在多行、比较复杂的程序上,非常合适,而且,在后面你还将看到,这种方式还可以让你非常方便地使用附加awk功能。

D*T4h8z1mS9Xj4b02.2    常用变量

'[R7T|w;t'Y0J0awk有自己的特殊变量集合。其中一些允许调整awk的运行方式,而其它变量可以被读取以收集关于输入的有用信息。下面列举出最基本的几个常用变量,并用例子一一说明用法。51Testing软件测试网-wL3IPm+g*r

*i DLY%@x\8vG0Awk特殊变量51Testing软件测试网%|3\:} ?0w6o

描述51Testing软件测试网uy$RB M:J

51Testing软件测试网la4h4S E8{rtV

51Testing软件测试网Z.ze"G&@]'X1O5{ C

$number

)VB#{Z6L%W }S051Testing软件测试网'aXX:n} ey ]

表示记录的字段。比如,$1表示第1个字段,$2表示第2个字段,如此类推。而$0比较特殊,表示整个当前行

+Rd*WK0}051Testing软件测试网 e3U*zc7f,^ v2wr

FS51Testing软件测试网e'e&P2?p{ g7Hk

BD1E.k }Z5dF$f0表示字段分隔符51Testing软件测试网E3t};m{6P!hC C

51Testing软件测试网#~MN%xi

NF51Testing软件测试网-g.S%C3uNuC2P(i

r+^/?(|] \)R;`\0表示当前记录中的字段数量51Testing软件测试网!m4e^6kO.B9X+G hb%N

51Testing软件测试网3n"he([`ha3F

NR

5h\0WoZ7Yl051Testing软件测试网8[z{O8\Zm(? _

表示当前记录的编号(awk将第一个记录算作记录号1)

z6uXO/K'\X051Testing软件测试网IN)A_it*L J

1v kHuo8Spo2v*d FI5W0

P1M~fT$q0为了便于举例说明,在当前目录下生成一个历史话单文件bill(注意,是一行内容,中间没有换行符),其内容如下:

^tc1@+_4[F051Testing软件测试网,P7Tp};eXJ1G

51Testing软件测试网9eb7rM7B)Z

4429300,0,8613902700001,8613902700002,8613800288500,2004/06/26 10:31:33,2004/06/26 10:31:33,0,0,0,4,6,1,0,0,0,,0,2004/06/26 10:31:32,NULL,1,0,0,nihao@,51Testing软件测试网GK Qg y [n5@E

e*a*b0P|&YR04429300,0,8613902700001,8613902700003,8613800288500,2004/06/26 10:31:33,2004/06/26 10:31:33,0,0,0,4,6,1,0,0,0,,0,2004/06/26 10:31:32,NULL,1,0,0,nihao@,51Testing软件测试网7_Qv8Km&O m9Qw&}

51Testing软件测试网hOLvAM

51Testing软件测试网9w$J _*Ko/g#?e~

)?RP W4}0我们可以使用$0变量将整个bill文件内容读出:51Testing软件测试网(k~6Lj3m7fq

S&ISIi0eQ,}0

/QdgD7p^3dY(N0$ awk '{ print $0 }' bill51Testing软件测试网)i(x2I8eQ'^ H

t'F8U3x@+Q051Testing软件测试网R1d Hbn+vPU\5jx

#^*{#N7Q8F~+?f/u)b)?j0可以看出,在awk中,print和print $0的作用完全一样。51Testing软件测试网_pBj[/mm+w

51Testing软件测试网O |%UiV1kf

使用$number变量,对多个字段的文本进行处理,将变得非常容易,它可以让你毫不费力地引用每个独立的字段。例如,我们可以列出主叫号码和被叫号码:51Testing软件测试网,K*KlbG

51Testing软件测试网1M"`X!pXeH N

;RLS&p8P0$ awk -F"," '{ print $3,$4 }' bill51Testing软件测试网:V%v FT'D%o;_

51Testing软件测试网6eU+{,z f$I8xCE

8|d9{S0F HWK:_051Testing软件测试网lU a;m(tG;^

上例中,在调用awk时,使用-F选项来指定","作为字段分隔符。awk处理后打印出主叫号码字段和被叫号码字段。而且,你还可以在字段中插入字符,比如:51Testing软件测试网5{w#?9kQ @1V W1c*X

&]B)n(u#e#y'K051Testing软件测试网6f*j#YW!o

$ awk -F"," '{ print "OrgAddr: "$3, "\tDestAddr: "$4 }' bill51Testing软件测试网 Gn`S L^

0od1U_jpa051Testing软件测试网\V~~1BiT

51Testing软件测试网 _7KO*|9kv$D

以下是该脚本输出:

!taG~7e051Testing软件测试网)b2kY1LQ4C*rqq

51Testing软件测试网y @K2l9F:UE-k-g;fr

OrgAddr: 8613902700001  DestAddr: 8613902700002

|d&i-F+n0AouG!D0

@/p z7i'B$T9|0OrgAddr: 8613902700001  DestAddr: 861390270000351Testing软件测试网+x^"AS N+nr)s N o

51Testing软件测试网 |2@,Q1}-fYdGF

p(x3Q0J#I e051Testing软件测试网@DR/|yb lL/X

以上命令中,我们是通过-F选项来指定字段分隔符的。如果我们使用的是脚本文件,则就要用到FS变量来设置字段分隔符。编写脚本文件bill.awk如下:51Testing软件测试网%_$JZ5_ V

D&x cB&zq L051Testing软件测试网y}}jx.z,i iQ

BEGIN {

:Hw Yq#Sa9OL0

ok0s!rt!S{aTW!G0    FS=","51Testing软件测试网n*F-X;sn#{TZ#d

2{M K&Ml,KcI0}

,og:R q9]t.a5|;wT`051Testing软件测试网8y ik!w Fu@"X7v*eG

 51Testing软件测试网@~(hm.w

2S?9s ?9H7z0{ print "OrgAddr: "$3, "\tDestAddr: "$4 }

q4Q+h3IT/nHO.N051Testing软件测试网:O0pL4I3C

51Testing软件测试网uu*_KH A-|[;{TO

4hTX2M4e1tJa0建议最好用脚本文件,这样方便日后重复利用,也方便修改。

]8u5r7v:lL0bJw-iU#^A051Testing软件测试网V#{$]1C`P {h.MR.C'U)X

FS值并没有被限制为单一字符,可以通过指定任意长度的字符模式,将它设置成正则表达式。如果正在处理由一个或多个tab分隔的字段,可以按以下方式设置FS:51Testing软件测试网-L`0{9q,i$G^

-I"j:UV b#x0

F;?%xY/intE'F-r0FS="\t+"51Testing软件测试网i5xI@D!gc0N^

51Testing软件测试网^fiAt

51Testing软件测试网2B&v'm3qi mb

|As9^H2R\0另外,这个脚本里出现了陌生的BEGIN,有必要解释一下。通常,对于每个输入行,awk都会执行每个脚本代码块一次。然而,在许多编程情况中,可能需要在awk开始处理输入文件中的文本之前执行初始化代码。对于这种情况,awk允许你定义一个BEGIN块。我们在上面的例子中使用了BEGIN块。因为awk在开始处理输入文件之前会执行BEGIN块,因此它是初始化FS(字段分隔符)变量、打印页眉或初始化其它在程序中以后会引用的全局变量的极佳位置。51Testing软件测试网O8S0GbAS3E9`p{+c

mYl~`W)`9C^0n0awk还提供了另一个特殊块,叫作END块。awk在处理了输入文件中的所有行之后执行这个块。通常,END块用于执行最终计算或打印应该出现在输出流结尾的摘要信息。

[u'{/@9kH_0

;yig#Vm4w f0NF变量,也叫做“字段数量”变量。awk会自动将该变量设置成当前记录中的字段数量。可以使用NF变量来只显示某些输入行:51Testing软件测试网F5l|JA3u]l V

51Testing软件测试网[!R a%w[

51Testing软件测试网%l@.},}D ZG(SK5|h4]

NF == 3 { print $1,$2,$3 }51Testing软件测试网(iAZ#Qw

8tuD1W9I6Pd a0

K MD xsl Cw8I051Testing软件测试网.P[9A3Oo/luU

NR变量始终包含当前记录的编号(awk将第一个记录算作记录号1)。迄今为止,我们处理的输入文件每一行包含一个记录,对于这些情况,NR就是当前行号。可以象使用NF变量一样使用NR来只打印某些输入行:51Testing软件测试网-f Qz,Y R2QnG-I

O5p|Y)R4c2tx O-hH051Testing软件测试网+oh@O VM#l

(NR < 10 ) || (NR > 100) { print "We are on record number 1-9 or 101+" }

g%yo|j&lRx051Testing软件测试网_ac R_Y+Rm(J-F

51Testing软件测试网u;jQ&frI](m

51Testing软件测试网]KFpg

在本文的第二部分我们还会讨论两个特别有用的特殊变量。51Testing软件测试网4\@V sAs4Rp

2.3    表达式和运算符

#ur1t7~4A7nH/{0awk 允许使用正则表达式,根据正则表达式是否匹配当前行来选择执行独立代码块。以下示例脚本只输出bill中包含字符序列8613902700003的那些行:51Testing软件测试网!YM;P:L2W/GU+W.xv

51Testing软件测试网$MZ-t*~.T$~

51Testing软件测试网+{&Aq7uv,P#xxTQ

$ awk '/8613902700003/ { print }' bill51Testing软件测试网_'B$a4c x

3z4bK ojn/p051Testing软件测试网 dK rj6`*c]|uY

*Y Wg'p8hD0当然,可以使用更复杂的正则表达式:51Testing软件测试网y ~I8X;~AX#H:f

51Testing软件测试网-wXx*L'DBr

e8g2f)G4a rcO:}X+C0/[0-9]*/ { print }51Testing软件测试网&IP$M7[(K$q7WL

51Testing软件测试网B*JIP Hoc

51Testing软件测试网ET ?&VC M u

.F I{#M(}.C0下面列出正则表达式元字符:

#E E g!}g!D051Testing软件测试网9~aS3vB5t

字符

)@*Vx;~@r0描述

{YPrk G0

|t+d-x ^051Testing软件测试网!os&}"XW!KN f;P9W

.

c0ShH`%K0

,L/KC@ s4l0可代替除一行之外的任何单个字符

}AhBLL,l051Testing软件测试网.@8~aY@o:o G

*

2~V$]l!N O051Testing软件测试网4s/Ez dAY {Bmo

可代替零个或多个在它前面出现的字符51Testing软件测试网 v `N/e Mn

fa |b4juCB0[chars]51Testing软件测试网k1\5hT!KG'DV+ie

51Testing软件测试网ho5oCZgZ3^@

可代替chars中的任何一个字符,chars是一串字符序列。你可以用-符号来定义一个字符范围。如果^是chars中的第一个字符,那么将匹配没有在chars中指定的字符51Testing软件测试网ZP#ZH,i

g3_m Eb{w0^

ct#c(Cdp*^0

Of2l(s?A.I0A0匹配一行的开头

E!EXvA ~/zbN051Testing软件测试网 cS1s.~Z

$51Testing软件测试网l1qr5~*I*\9F,YG

!L&Od;d$S0匹配一行的结尾

-s/k#mE_&ey&o0

@w s3yh1y+k0\51Testing软件测试网:ze;L4{N

51Testing软件测试网Q[rY.u ?4o

把\后面的字符照常输出,通常用来转义(不使用特殊含义)一个元字符

y8twK+@051Testing软件测试网&zA \D h-aj;J3g:`

7bP IDaIJ051Testing软件测试网;nYJ r+D6o.f

除了使用正则表达式来选择行,我们也可以使用布尔表达式来选择行。使用方法是将布尔表达式放在代码块之前,仅当对前面的布尔表达式求值为真时,awk才执行代码块。以下示例脚本将输出bill中第四个字段等于8613902700003的所有行中的第三、四字段。如果当前行的第四个字段不等于8613902700003,awk将继续处理文件而不对当前行执行print语句:

c^fQrm M^ Y051Testing软件测试网;ji8p^@0H.T.AU

SD3E&Fg A(~TF(o0$4 == "8613902700003" { print "OrgAddr: "$3, "\tDestAddr: "$4 }51Testing软件测试网RMSFj`

i~z+?J7bQ0

9A-E3Wfpx/Fj051Testing软件测试网,MDT&ViE R|v"SV

注意,代码块前的布尔表达式必须与代码块在同一行上。

/OVc'U|m"b051Testing软件测试网 }2NYFlt

awk 提供了完整的比较运算符集合,包括"=="、"<"、">"、"<="、">="和"!="。另外,awk还提供了"~"和"!~" 运算符,它们分别表示“匹配”和“不匹配”。它们的用法是在运算符左边指定变量,在右边指定正则表达式。例如:

x0Oh y4\4t8b051Testing软件测试网sL`RHMB`"S

+GT2M%l7b:vX0$4 ~ /8613902700003/ { print "OrgAddr: "$3, "\tDestAddr: "$4 }51Testing软件测试网+eV7L`.W K*@#NB

51Testing软件测试网6Q#TVla!J

51Testing软件测试网(dh)`NW

51Testing软件测试网 Q6kN XJ

awk还允许使用布尔运算符"||"(逻辑或)和"&&"(逻辑与),以便创建更复杂的布尔表达式:

G O"}P7SZ0

*z`2V1q ]8F1`,j V8n051Testing软件测试网k5ZR:`6C9x

( $3 == "8613902700001" ) && ( $4 == "8613902700003" ) { print }51Testing软件测试网2bMZAy

51Testing软件测试网7Z:A Hr5M6~{.e

51Testing软件测试网+FVCM9f%k4x2T.].w

qi)eflIL$n*N l0awk的另一个优点是它有完整的数学运算符集合。除了标准的加、减、乘、除,awk还允许使用指数运算符"^"、模运算符"%"和其它许多从C语言中借入的易于使用的赋值操作符。

l?~)`@:m0

@4W|i&a-X0这些运算符包括前后加减(i++、--j)、加/减/乘/除赋值运算符(a+=3、b*=2、c/=2.2、d-=6.2)。不仅如此,还有易于使用的模/指数赋值运算符(a^=2、b%=4)。51Testing软件测试网q"h)Nd6J@rs|I

2.4    字符串化变量

?8M)V$q F aK{K M|0awk变量“字符串化”是指所有awk变量在内部都是按字符串形式存储的。而且只要变量包含有效数字字符串,就可以对它执行数学操作,awk会自动处理字符串到数字的转换步骤。请看以下这个示例:

$a7P IC ZSL0M0

G lo4Gzj3T^?0

2LY8eP:HR0BEGIN   { x="0" }

b7L&a9]qLVL/t\9k E051Testing软件测试网-?+`!J3nH

/^$/    { x=x+1 }51Testing软件测试网VV3d$~u

51Testing软件测试网Q X1Rw+BL#rQ O

END     { print "I found " x " blank lines. :)" }

EQe+a;~cuyA051Testing软件测试网@#v4{M&m

51Testing软件测试网!|$[K.t7e ]9y-y

2x9z5sg.I XT[D3@P0这个例子的功能是计算文件中空白行的数量,^$表示空行。

9t6cJ GD3l)_$Me V0

C3o/M%Y4R)A r,s YB,Rm0如果做一个小实验,就可以发现如果某个特定变量不包含有效数字,awk在对数学表达式求值时会将该变量当作数字0处理。51Testing软件测试网U[;\t ~;e,j] Ah R

3          第二部分:提高 3.1    处理多行

`(XCebh+| Q0在这一节里,顺带着讲一下三个特别的变量:

xy/aKB/hW051Testing软件测试网4z3V"p1Acyh?&}v

Awk特殊变量

;]]/K'd,x-~/C0描述

R"}-m8e{?051Testing软件测试网*dn4YI5f P I

;B4D2l:QZ1VNB0RS

(ETw&Y[051Testing软件测试网#nzOj.R f+e

表示记录分隔符51Testing软件测试网.Q5j {9v)L Pr

m\N7@SQ0OFS

L7c/x/S \/uE.iV0

1`@e~,oI+Y0表示输出字段分隔符,在两个单独的字段间插入定义的字符串

5J1_5t!P8E5o051Testing软件测试网Cz'~&Sp1D)h&|

ORS

h?w PpO~051Testing软件测试网\ H yi.d*V`*Q%I

表示输出记录分隔符,在两个单独的记录间插入定义的字符串

S"y(a;A V#\V?k+K051Testing软件测试网)B"m!o&Hr2l}z2T"}

51Testing软件测试网R6o WHz@

G8y!Gy'?wsXx6u0第一部分我们讨论的都是一个记录占用一行的情况,如果要分析占据多行的记录,除了依靠FS,还需要设置RS(记录分隔符变量)。RS变量告诉awk当前记录什么时候结束,新记录什么时候开始。51Testing软件测试网&o/hJ/z,S

.H y~2vs0为了便于讨论,我们依然首先在当前目录下生成一个通讯录文件address,其内容如下:

2r hI`g.V051Testing软件测试网 K]w:\ Z&w

51Testing软件测试网4NPmM%Kk

zhangsan51Testing软件测试网%a\fVDz

51Testing软件测试网!p \~%c(Q*A9?%t

1371234567851Testing软件测试网uq F,c-^@

k4Q R N(Ein*b4Cl0zhs@hotmail.com51Testing软件测试网1bDZ:m~ bXh

51Testing软件测试网.Pi u'OY]jO-L`

 

:IGx-j&z7B/X"v)we:HJ8Z0

|h-L m-fe|I0lisi

z v[ j`ouI!m yE051Testing软件测试网-I;T$^g7})_R

1301234567851Testing软件测试网W?nM |w+R"X

51Testing软件测试网~nW.^6v

ls@21cn.com

N9G!QvUK]'}0

"KD D+hI7T&| dN9F0

M,KFFke f sL*]o0

:A2W"M![5Ds+n0要处理这个文件,可以将每三行看作是一个独立的记录,一个记录包含三个字段。如下脚本将原记录由三行转换成一行输出:

l L f*i:YKj'Jt({051Testing软件测试网;Vz-ga ~

&hcXYWW} J^0BEGIN {

"P2lF@Hcg l^?051Testing软件测试网)Y;N|H/c'x

    FS="\n"

-D&x \H c0

'j[L H#\4h0    RS=""51Testing软件测试网,Yh(h { E)v

51Testing软件测试网;d-^'f{$Y"R5{2f

}51Testing软件测试网.e cd{[O|

51Testing软件测试网2W;U4z6[J"NJV

 

7`xD$m z Y [7__0

7u7{Y6TU4Y5c6G2^0{

*r Ioc+dE-Lvyv&@0

KGp^-Pr?\$j6O0    print $1 ", " $2 ", " $351Testing软件测试网@&LM _2MNe;X

51Testing软件测试网 f'd'g9ov)`a1m:t

}51Testing软件测试网cC%@-x C7_$W6g4C^

V_\;q]U O051Testing软件测试网 [5I)jXh&X?

4a5Kd}-a0此代码将产生以下输出:51Testing软件测试网&H;{@@)`"x!n

Jx%zxYb0a&i051Testing软件测试网s-?&~-~2[(v T'VlF~

zhangsan, 13712345678, zhs@hotmail.com51Testing软件测试网^3_ i$DMg$d}

51Testing软件测试网0p1?'[;]R?%S6A

lisi, 13012345678, ls@21cn.com51Testing软件测试网/B3n.p)JID8nN

51Testing软件测试网3~mN7q tr6^d

51Testing软件测试网.F*fL t~q P

e2p9`-X^T0在上面例子中,为了在三个字段之间插入一个逗号和空格,使用了", "。这个方法虽然有用,但比较难看。其实我们还有更好的方法,那就是设置变量OFS(输出字段分隔符)。OFS缺省情况下被设置成" "(单个空格)。使用如下脚本可以达到上面例子同样的效果:51Testing软件测试网\$?0A)P J

51Testing软件测试网'G } irHp*r7j*k

51Testing软件测试网9@$T([9J"~

BEGIN {51Testing软件测试网 A&{4qQk ?7a

51Testing软件测试网/m/K8gSU i

    FS="\n"51Testing软件测试网"NQ*Jv"wSMz

*y/K%jN"DS0    RS=""

KE#Z v'L8|T t"m0

+x_1{Q9Ok9l0    FS=", "

%X#`e,PfJq(W&vc0

rT9wM-Se6y0}

&tN*g5d3p9|i"U0

;H*PN.U6}~Zd#Cto0 

iHl e @ _#N_051Testing软件测试网$e:n E5w%@

{

'KQ#[(?d/eXw+x&p051Testing软件测试网:|1[a0L7r7mHp

    print $1, $2, $3

r,i5aQ}%qN:f0

s bRS)y/uP k0}

0D/hN3H9iG9X2u&M051Testing软件测试网/sG'j5r&E/m-l

rqO8u2bo6x051Testing软件测试网HS]FB4|

awk还有一个特殊变量ORS(输出记录分隔符)。ORS缺省情况下被设置成"\n",如果我们将其设为"\n\n",就可以使输出记录的间隔翻倍。例子就不举了,大家可以自己试试。个空格分隔记录(而不换行),将ORS设置成" "。

q V|T)bEg0CIp0`051Testing软件测试网1erP4g HP4VY{`

需要注意的是,使用上面的方法,最多只能处理一个记录占用三行的文本,象下面一个记录占据四行的通讯录,就处理不了了(大家可以试试看):

s'IaWa!H+y1rb'Io5~0

&r J\;B,cOxb em051Testing软件测试网X"V_/Q*G,}

wangwu51Testing软件测试网Np%l!^(_"fG#M8o

51Testing软件测试网-I"|X fRP

13512345678

y5P wZ c2KEM0

-l'bR4Z"]muI8G"L#{0ww@163.com

Ex7Xed'm8B+f"HZ0

ao {-k-p0wuhan, hubei51Testing软件测试网J_l!F&S8TS

3Y"k:u,G-iY`8a0

(Sxzzm;T7H p0

N3K"z:nC5}0要处理这种情况,代码最好考虑每个记录的字段数量,并依次打印每个记录。以下就是修正的代码:51Testing软件测试网S:N.i5k0wR+_

$R'b8~ u/EM!L5r051Testing软件测试网m*Nv5S6s Y`2]5_4[}h

BEGIN {51Testing软件测试网x+CB$Zt g

51Testing软件测试网(r$IXv)H:?0R T d O

    FS="\n"51Testing软件测试网md TBs/s

51Testing软件测试网 pmk t pn%hc

    RS=""51Testing软件测试网P3^ qsus1w ]

51Testing软件测试网&c,}9i1D W-sE6S-j^

    RS=""51Testing软件测试网u(t"T2W.qB;l

.[f5f*Ev g0}

"z:~'y!T'Tf Nu%H[2D4v8S051Testing软件测试网&a6M)`#U7s(X

 51Testing软件测试网J _7f;T8Mr)Ec

6YIEP/K.ro0

y0jG#f X2R8L8x'k0

!]W$e2e!]1KL Z9`0        x=1

UL7h{k7M c%O8f0

uH;j!a2fV |0        while ( x<NF ) {51Testing软件测试网%\c^4Dp ^

51Testing软件测试网:g)@9yU*TR

                print $x "\t"51Testing软件测试网3C2f-uW.H j

51Testing软件测试网6w C'WeTM{s

                x++

e2\0G5Lt,X I x0

Rf8@n5Qx0        }

su mc8@,M0

`VOv0F q0z X&|0        print $NF "\n"51Testing软件测试网/~ O+A-x [ m Y0^ d

51Testing软件测试网1J0Zz9t`/vYp8j:V-X

}51Testing软件测试网T4c9oH;~8sm

51Testing软件测试网.b%Nq,VgU o5d

51Testing软件测试网a g.Z1[5~ D1X[

^2XJVG8U_0程序输出如下:51Testing软件测试网n;NcV+HG Z&N&jN5|

51Testing软件测试网x0U(GM/?_

8ZFU:`UO)f0wangwu  13512345678     ww@163.com      wuhan, hubei51Testing软件测试网 @|8P e j

51Testing软件测试网t\ UQ-w0SP

51Testing软件测试网 PX4\8]"vn(s

3.2    条件语句51Testing软件测试网:zG)O E*j)I

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

/nN#D4?mB0

m!R/~ G)g9l0

dw*P9[s#y:?S(^0{

u Hc9mw:Lu4C/p051Testing软件测试网Qk"j6T Q$xF L(^

    if ( $1 == "foo" ) {51Testing软件测试网MTKVt,A,M

51Testing软件测试网*Hp$v&@F#M'AF

        if ( $2 == "foo" ) {

6\,lFe1Yg8S#F051Testing软件测试网MaR%Ah#ff

            print "uno"51Testing软件测试网.t&E2N~ k

:|(m?2P4Kaj%`W,p3T0        } else {

rvM`%F#b2]0

"@I ^KZ0~+Q0            print "one"

X$ip)PLZ/iA051Testing软件测试网I8|(^[|TH_

        }51Testing软件测试网cT:[7dCBX

s:l&L8Yr;\0    } else if ($1 == "bar" ) {

V:Y"Q p.h fIX_051Testing软件测试网*cD!` r \!^;R

        print "two"

V!a/X}/t3z2^051Testing软件测试网G1o@FOE

    } else {

ng6G"B-|r6K0

e(j2{ TD4_0        print "three"51Testing软件测试网 |R*}|i4v6?*K

Jd gd|l0    }51Testing软件测试网S#W4J0s!Uh)Q%h)LO

51Testing软件测试网8yX?Ar

}

+pju[i9CN&a(AA0

;_O7_8l"KB&B-Tj0

-P2o/kf~%N(E03.3    循环语句51Testing软件测试网8`5ys4e"{#u

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

n!ePFw?^ e0

E&OQIzO m0do...while 示例51Testing软件测试网jaX9L,fE4[Q"^

51Testing软件测试网 oiC3x%h?$K1P

51Testing软件测试网 scA J`,@-GT{

{51Testing软件测试网;|9y(H3Q+XH kXKCx

3J5Wvu4A0    count=151Testing软件测试网$Si8\_t E

S6[4fJE9d K[0    do {

B.Y9RcU L051Testing软件测试网'E"hg0Sr

        print "I get printed at least once no matter what"51Testing软件测试网MWz r5_m

"W(xu3\f^0    } while ( count != 1 )

ds G$G1_051Testing软件测试网r1HWH#HB,n8}

}51Testing软件测试网z*eC["h"B*bN$pF

51Testing软件测试网 s2V#O A?x

R&q7E [/MP3J0

`2Eed8[8S)hr+j0for 循环

+vXk~{&h u Q/P U051Testing软件测试网K hj:\r x

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

H |u{X!U*[5e mr051Testing软件测试网E@$y$E+y)z4Tv7xN

51Testing软件测试网9B;xH3|0l GKZF

for ( x = 1; x <= 4; x++ ) {

b Yima.f!J0

6](t#Xh#m|rI0    print "iteration",x51Testing软件测试网!Rf&q L2['^

:N#uJQ2f)j(p(]0}51Testing软件测试网k Sh5e \ F?o(W_B

51Testing软件测试网 n8Do;fIH)R

51Testing软件测试网,m oww|e

51Testing软件测试网QQf/`|*|!w!}\h c

break 和 continue

8c3@Zt0tWb^5L(GW0

Nv5| NFl#IQ0此外,如同C语言一样,awk提供了break、continue来控制awk的循环结构。break语句用于跳出最深层的循环,使循环立即终止,并继续执行循环代码块后面的语句。continue语句使awk立即开始执行下一个循环迭代,而不执行代码块的其余部分。51Testing软件测试网mQ]/U*Y"|"H#Ei

3.4    数组

nfavg7u?a p0在awk中,数组下标通常从1开始,而不是0:51Testing软件测试网3CRbw sk

51Testing软件测试网!p3AN }1k#aT&}5_

\i$|4Mf!r r0myarray[1]="jim"51Testing软件测试网4NU,us%I

51Testing软件测试网!s)@v!MV

myarray[2]=456

"h]/KF-r5S }3t0

q,[ N'P!L051Testing软件测试网 tMEdm2K&w

51Testing软件测试网:y-fN'B*G,bA-\])w

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

*x%^3o0X N}0i`0awk可以使用"in"操作来遍历数组中的所有元素,如下所示:51Testing软件测试网a` X2dA

51Testing软件测试网;V$^ Wi*p5m7ZocnnJ

m MGtf0for ( x in myarray ) {51Testing软件测试网;OBI*m#H aD;q6@

51Testing软件测试网4JL ^,[H B

    print myarray[x]51Testing软件测试网.XsQ w)[)S;e+vT

51Testing软件测试网%o9~mHj!M%\df

}

'sd*A;a%@X'f051Testing软件测试网5FgF_bwW

51Testing软件测试网 k/`"I0[O F1\#B

51Testing软件测试网)x8i%K x~/xa^

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

SH si'[S$c)u0

\)M(T|:T$jV~ p~ c0jim

,b;hT+]7l*|0\ I0

E5N)e,p!fGX/O q^^0456

0atWvH \}1K051Testing软件测试网7TL6E D6v0f$Bs

!v g!ED$S5G051Testing软件测试网8w d7d'G9X/e P\

还是

Is x4Y!\G`;ER0

?#DJ`2P/J$w W051Testing软件测试网.a1W@ t s HR,O%SF]

456

,Q|ue5g-y051Testing软件测试网 A"[#NjJ"]0w[/A

jim51Testing软件测试网.C/W@qD$on$D0x

51Testing软件测试网P3@\$`x^{

51Testing软件测试网Ka$B?X'?/X

Sz }b:f4L9gk U0awk数组中还可以使用字符串下标,其实,不管你使用的下标是字符串还是数字,awk在幕后还将其认为是字符串下标。举例如下:51Testing软件测试网 GIqXm:n*e

51Testing软件测试网/sk!u!}%~Kn

代码一:51Testing软件测试网:M[T&pk8nd

51Testing软件测试网qDHe3E

51Testing软件测试网6o r!o7MS5Aw#j0I

myarr["1"]="China"

~{)}&u1j"a051Testing软件测试网&Cx P}!nC+h

print myarr["1"]

/Z5C;KTfv051Testing软件测试网jc:?{Yy

51Testing软件测试网YF+wg@}^

@#|Y!i-gQYfE,q{/CW Y0代码二:51Testing软件测试网R[o7s-vD,w'c

5pK5K `6F051Testing软件测试网xy4a.GWU

myarr["1"]="Mr. Whipple"51Testing软件测试网&?3eKJ m U#l#eM*rD

51Testing软件测试网MZSNYfw!u

print myarr[1]51Testing软件测试网Fk U:f_vmi+n A

51Testing软件测试网;Q'Z+pm%[v,H#n?

1EV"j0~9^![%_lA051Testing软件测试网|w`klnot

代码三:51Testing软件测试网 n WP h8Ly(TZb

51Testing软件测试网?Z ]`%vl$|V[

G @|D9h;i4Q's0myarr["name"]="Mr. Whipple"

| nmk g4F051Testing软件测试网*I]OQii

print myarr["name"]

9fJ)i{6k8e+G,g8B R051Testing软件测试网 | U}v;[)zW$@N

51Testing软件测试网u? \w"j\

tML@ J&Rj Gm O0它们都将打印 "China"!51Testing软件测试网@X,dUTi?K

51Testing软件测试网'O}4L1]Y6W/Z0@6QP ~

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

^$b/Epx+[/t'zqt.}{n051Testing软件测试网AMtr7a'[

51Testing软件测试网&A-m1G F!M+y

delete fooarray[1]51Testing软件测试网{dt3Q5O?-Z7e _h ?

51Testing软件测试网W{8A8_$mI

51Testing软件测试网E;}?Y#F`+j

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

r4RQV1R5jkk051Testing软件测试网#`6R(l$a4B Q o/l"_ Q

/y3G?(N'mz6E2^0if ( 1 in fooarray ) {

l*@uJv4Z q U0

d)Lq5])E#vO0    print "It's there."51Testing软件测试网@t ?cX

51Testing软件测试网3CC[8@w

} else {

qZp%P5}\2T2oy7H051Testing软件测试网I~5b L3P6w

    print "Can't find it."51Testing软件测试网3x2rK-[1KoP{$w.R

8GC+E6R @6k0}51Testing软件测试网y7ei5M-mZVF

51Testing软件测试网 g5Q ^^ vp^

51Testing软件测试网9X!Y"b1I0\*k%R })vt:k

4          第三部分:精通 4.1    格式化输出

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

wzI#Kv[0

n"Y&Aae;e5h0从下面例子可以看到,它们几乎与C语言完全相同。51Testing软件测试网J{ WZq0]T)h

51Testing软件测试网8cqi'GL h

51Testing软件测试网m+aG,}Y9m

x=1

H\ u/y#|%P1UBe0

C#I|)Mm0b="foo"

_G&^FET051Testing软件测试网,} ~$}&em:iv

printf("%s got a %d on the last test\n","Jim",83)51Testing软件测试网bc#wB#K!\H(?YP%R+M

51Testing软件测试网:|4EJ'L2I r'C&[ Nj

myout=("%s-%d",b,x)51Testing软件测试网{ e8o"c$wU7g4L

)J dJcKtb0print myout

oq h0q,]051Testing软件测试网dXhl._2^A\

'SU QR#JT9y5]j051Testing软件测试网$]eG[`!uJI

此代码将打印:

-pY1g"d8^$FI&\0

f5E w8d6[g0

Za{9cp4L~!a%e1X0Jim got a 83 on the last test

?1k2a?1\0

h~3O.if4WJF0foo-151Testing软件测试网4X/\S`1VM

YIXM{+holt0

:f,{7PZ4y&T04.2    字符串函数

1TPV X?{n I0既然awk把所有变量都当作字符串处理,那么字符串处理对awk就显得尤为重要。但要说明一点,awk不能象在其它语言(如 C、C++)中那样将字符串看作是字符数组。例如,如果执行以下代码:51Testing软件测试网C0z IV5cK

51Testing软件测试网yGLi U G

$L(\,B1c zS}5v0mystring="How are you doing today?"51Testing软件测试网&K9w_%sN h8x

51Testing软件测试网@X_'k0Z9X

print mystring[3]

W @i$m|%^d8v051Testing软件测试网[{ Z/ACw

G(S!^ R1` |051Testing软件测试网F+mM5d Sj;zB

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

at!s4T:z0

5S7_I kY@ J0

^#xz^+C0awk: string.gawk:59: fatal: attempt to use scalar as array

uo~^coLA5Q_ Jt0

x~;Oz-nU:m Y0

E4H!~.Sc\0

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

E(`2b0E7iw051Testing软件测试网eI:e&hZ(J}B9r

字符串函数

2wBuD)]CfS0描述51Testing软件测试网,PY"sP}c#\9RA v

51Testing软件测试网j.F4~&vll2e?

51Testing软件测试网 nC;?%F.CX^(JU

length()51Testing软件测试网!MK@ u` h/f

/j&_uk)B4@"|L0返回字符串的长度51Testing软件测试网Aq3Y"f/V-@)V2^SN

51Testing软件测试网)QcoGMv8t2|l SL$d

index()

w4OtQ? C k051Testing软件测试网P3n4v|e1x?y6\

返回子字符串在另一个字符串中出现的位置51Testing软件测试网,oqb{$A/y]

ppk K#k@%EV }0tolower()51Testing软件测试网;c(K%f$Ia$_yA

!D:J})~8T|L0返回字符串并且将所有字符转换成小写51Testing软件测试网z9G6b:~N8t1O

51Testing软件测试网!h:r*VSxX

toupper()

*o4|d|8SE.}$y5n,BF0

{`.m!R(Ws%g0返回字符串并且将所有字符转换成大写51Testing软件测试网#d} cR*_*G(~a/L

'b|0r+Sf0substr()51Testing软件测试网 ]G7L#{D5Whl

4b Y*m'i)bD;xB?0返回从字符串中选择的子串

Q\%U-ds6Z051Testing软件测试网`#T]O Z?2fy|

match()51Testing软件测试网i&V'xbU HR&]yM(V;q s

51Testing软件测试网L&hfM+|C

返回子字符串在另一个字符串中出现的位置。它与index()的区别在于它并不搜索子串,它搜索的是正则表达式。51Testing软件测试网FN F Q3Q[^4B-Z

51Testing软件测试网%mm8x9]0Y7X~_

sub()51Testing软件测试网O"E3NH K6N+d5h2Z

51Testing软件测试网7f&K:r-Skte6p

替换匹配的第一个字符序列,并返回整个字符串

rDw*bwV0

c2EiZ/ga xa&h0gsub()51Testing软件测试网!vT.Jz0Kdyf%{l

51Testing软件测试网`/n?jKV._1Ssfs

替换匹配的全部字符序列,并返回整个字符串

0A2QnN!W.G eW,bM051Testing软件测试网#q'w hi*DU#o%P){q

split()51Testing软件测试网'u'\)c-w{;v^p2d#y

.}X:sbs!c;n'Q[0分割字符串,并将各部分放到使用整数下标的数组中51Testing软件测试网#C#U6\Q3h!u/i(F.jj}

51Testing软件测试网 d[,Sr9a"L

7fD3ZbH6W3yV+K0

+p `,c3o,CB&WEC0length()返回字符串的长度,例子如下:

4lt&S)e.U2vMrJ051Testing软件测试网8]!a8}W7A3?VTl

5H/i7exd0print length(mystring)

/{^%aX4]0

#_/a~3x NU0

U)KEWfS051Testing软件测试网0g*I"l]/K9_A^'l?

index()返回子字符串在另一个字符串中出现的位置,如果没有找到该字符串则返回0,例子如下:51Testing软件测试网.}3u:ay%`(kA

+H%ha6rE,qb eD051Testing软件测试网eU.fl k9y

print index(mystring,"you")

1Faw$h(i(wo L z051Testing软件测试网(j:N0S3RAcCg

51Testing软件测试网[%F/l*Ch"VZ-i

SwGvT0tolower()和toupper()返回字符串并且将所有字符分别转换成小写或大写。注意,tolower()和toupper()返回新的字符串,不会修改原来的字符串。例子如下:51Testing软件测试网v)]!Q?tB{W

51Testing软件测试网-h#^|k~K%c0p`

+AB9G[1[m D0L E0print tolower(mystring)51Testing软件测试网A Z!I7O$PO2S

y$bX c-lS#szi0print toupper(mystring)51Testing软件测试网.hH+P!y;~n

nSQOS8X051Testing软件测试网%sh5@T.K%l

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

I~2}s7H0R0

+N,d-`6N"E6[2X,ed0

w9LP5@6r.J0mysub=substr(mystring,startpos,maxlen)51Testing软件测试网[!KL/T K

/Q/b2f(oZ{051Testing软件测试网hX$['xj CYf

51Testing软件测试网 c vOzP&N$C whB)h/?

以下是一个示例:

5h@yd#v%md@)EQ051Testing软件测试网nRxkG W&M j

A.{ v/N7^0print substr(mystring,9,3)51Testing软件测试网zJqtN ogs

O:Rx(q q o!I0

Rc#@{ AlQz h051Testing软件测试网+w&N }:wC,m[

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

.Z4X6|U$v5M?051Testing软件测试网6^Vt]|hZ&H0M

51Testing软件测试网]3m`.u+Up f

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

v:z_ nG8Z0

#P$F2P4N,{"_1[051Testing软件测试网 g3e:^.R+Dg

51Testing软件测试网 `_ Mu&Bl-y,W

sub()和gsub()是两个字符串替换函数。sub()的调用方法如下:51Testing软件测试网:n\5T"j OD2s

9TA:QH2hkpBK051Testing软件测试网gW:D6g W+V9U%N(ep

sub(regexp,replstring,mystring)

'zk"Wf5a&H2y0

h/a'C,G8NT#Z051Testing软件测试网)JwPE5X5Q

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

TnX~ Trux0

5j7Ld?&Mr0

O%ND$K8jH,l V0sub(/o/,"O",mystring)

)W3@%W$\qzF#Sb)dzH051Testing软件测试网 E/[R Z8OY FM

print mystring

7@z&W-{T;N Xb051Testing软件测试网b3pH7]}

mystring="How are you doing today?"

,gE&h$B1|W0

%d\H7J.~C?F0gsub(/o/,"O",mystring)

#vPn^:x1` X~`051Testing软件测试网F1q6y0_/E5c

print mystring

}"W7b6R o a051Testing软件测试网/@r;O`t[#A

51Testing软件测试网9@i4uZ%{#w]C

6U7@,m i fdWJ0其输出结果如下:

,x7z$ab LN*x+w[&a,yQ~d0

]b/fB C5@{'j!H0

h{-q/|!pR#|Y0HOw are you doing today?51Testing软件测试网 b:g*Z"cxX9o/t

3f yZKIxP0HOw are yOu dOing tOday?51Testing软件测试网"kCD j~ }a!v

S6u@~5z}(`X0

TkMuxWH-_0\051Testing软件测试网*h`Q7M-_t(f l

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

.a.S;a{p+a"CW R0

Pnv7eqOs0numelements=split("Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec",mymonths,",")51Testing软件测试网 c'ue/NN#f2u"i

fI*sy5d'PP0print mymonths[1],mymonths[numelements]

ew%w {&n%B/ik"}-{0

ri#Z7a$F"Vx&D051Testing软件测试网$Q,k!nh5P|jv

x5[8m&AX0其输出如下:51Testing软件测试网$cg+` fr7@Y

/s\Ri:bY!wMkO051Testing软件测试网$y9ive D

Jan Dec51Testing软件测试网(p/@&y4Uu)^.G*] Qy

51Testing软件测试网 S i}7c(nL!v,n+I

u'TLn P$oe(a051Testing软件测试网A4u`'VxW$n2e j$]!D

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

K4p`z q'U0

*Au,c(e^ L/[q0{51Testing软件测试网"sE*n Gkmlm(Y

51Testing软件测试网6Dg+v"u:?7KL;Dj

    print length()51Testing软件测试网tJ0[;w%P

x:YkgV{W0}

5WA|!u$q!}0

B9J8_ L"uR;ax0

ekIR#D'F|-O0

a3WP"h@O rP0 51Testing软件测试网c(d Q;~D-GGW"\

,e$b,e)Zl$m)s051Testing软件测试网VyK%TENed N-I
 51Testing软件测试网;v4M ~,AZ:y6q*w

51Testing软件测试网j$W @{ ORa8bp9u/n

参考资料清单List of reference :

a0x$rwamT.F0

3s#el5iJ5E1gP b#R1k c0[1]    SAMS, 《精通shell编程》51Testing软件测试网\'UL(|r!p

51Testing软件测试网 P@%VT:m.lN/|(YD

 51Testing软件测试网:H3C3As o*L#~Az i

{bPJ E.bFy]+xf0 

.i'H7T:b c~ [0

TAG:

 

评分:0

我来说两句

日历

« 2024-04-28  
 123456
78910111213
14151617181920
21222324252627
282930    

数据统计

  • 访问量: 109840
  • 日志数: 89
  • 图片数: 1
  • 文件数: 15
  • 建立时间: 2013-03-01
  • 更新时间: 2018-08-23

RSS订阅

Open Toolbar