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

DNS和awk

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

9H,o5`Bu {_o0此贴主要介绍小侠在COP亚马逊环境配置DNS的经验,如果哪位大神有更好的解决方法,欢迎回贴指导:)51Testing软件测试网^LX)S3_A*g

51Testing软件测试网/@'v1fW.yEE+i$y e

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

51Testing软件测试网5{dN"S(D FNL+t

亚马逊环境域名www.sdpcop.com为通过万网申请的付费域名。配置了泛域解析,即所有.sdpcop.com后缀的子域名都能解析到亚马逊环境的服务器中,例如a.sdpcop.com,b.sdpcop.com或a.b.sdpcop.com都能解析到亚马逊环境同一台服务器中。

*bd#cL"z s*j c0

F_k+`wn)\0引出问题

wb2p,R8dC8Z3Mj%^1[,~~051Testing软件测试网0u;D].L/lf:F

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

Ac q![:V!DH!u0

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

/s:sfVX!d051Testing软件测试网!MtYt\

解决思路

(T;nY|2V6a4SQ6y1N0

#A}%N/_,YB0将商用域服务器设置为亚马逊环境首选DNS服务器,专门用于解析xxx.test.sdpcop.com类子域名,将此类子域名映射至测试域服务器IP地址。即xxx.test.sdpcop.com子域名可解析至测试域服务器,剩余的xxx.sdpcop.com子域名保持默认映射关系,解析至商用域服务器。51Testing软件测试网.R/i"N3XW9Ez

-`?)dJ#@*mf!@^0操作方法

.i0mw)f_2[s051Testing软件测试网 ^5I%W+Ta#]Y

                                步骤 1     将商用域服务器配置为DNS服务器。

5bV5x`y&f(L;q4R7E.j051Testing软件测试网"b F Pkv:O9n

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

?N D Vx?7_ P#S051Testing软件测试网)c HA?!|`_5x h[

b.         安装bind组件包。51Testing软件测试网JP%p({b,Y9qIP

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

-jVJ&wO KqFZ051Testing软件测试网\9|T0r![RC

c.          在/var/lib/named目录下新增域名解析文件,包括正向解析文件与反向解析文件。51Testing软件测试网4v$kW j]}8`#G'I

51Testing软件测试网E^^%L v-Dw{*K |xgZ

# vi test.sdpcop.com.zone          --增加正向解析文件

:}3V;G0Qe)baJgTZ051Testing软件测试网t#HZd g/F x:tB

$TTL 1W

nE#\T&W0

-U8_@;Ft0@               IN SOA  test.sdpcop.com   root (

O.l#Dc3R-{@{051Testing软件测试网 qM+H&qF1Pq h6F%]|

                                42              ; serial (d. adams)

#R O3L'|q0

,_U5Gtu0                                2D              ; refresh51Testing软件测试网2z)aNAY.aL.UC

EUFp%c+n*r]${0                                4H              ; retry51Testing软件测试网 L ~)kJzqud

Dx*o'Z8S#Kw)G}!S0                                6W              ; expiry

'xe3R&_;DvJXkj7RRU S0

{['| T\0                                1W )            ; minimum

9c](scW0q,w4w051Testing软件测试网j{FA~Z$?F$r

 51Testing软件测试网 [1J.S%tt%DE c1o

E)g-@Vt'BrQYb0                IN NS           test.sdpcop.com.51Testing软件测试网)L hO-irLWRH

}@O ?}!Ot J0                IN A           10.80.82.5651Testing软件测试网g;F7\ P-GC

51Testing软件测试网o(Ok {,f+LE9Y0g(j

dns            IN A           10.80.82.5651Testing软件测试网&B)j*v.O9n'gc8A

:\4d2ZIe~H;V5U#G0*               IN A           10.114.153.230

,O~j!P:zSj-q`051Testing软件测试网(w^I:@Xrw

test.sdpcop.com为设置的域名51Testing软件测试网L]bSa#x[jsy

51Testing软件测试网 {W,X7bH-]b

*表示对解析test.sdpcop.com所有子域名51Testing软件测试网b-b^z5THme

/[`|7FW kP @010.80.82.56为商用域服务器IP地址

/gy/J!}n2k3_$^.b0DW D051Testing软件测试网FCF7i8ww)I Jg

10.114.153.230为测试域服务器IP地址51Testing软件测试网]:V2P)P1Kb:m

51Testing软件测试网vv`1g.?/@q*|V

 51Testing软件测试网Q7^9|`#p

51Testing软件测试网 t^*X$u/uj!hY

# vi 10.80.82.zone     --增加反向解析文件51Testing软件测试网+lG bx&^+?

vx)`,P qzte&y3L0$TTL 1W51Testing软件测试网 ydc*\,t3B1K#u,wQ

51Testing软件测试网C3sR.QRe5u*Z?(U

@               IN SOA       test.sdpcop.com.   root (

4B7Y Z(YYdD051Testing软件测试网 d0KJN(uMuh sE

                                42              ; serial (d. adams)

{d/Zca4F051Testing软件测试网9Vo~/t~B$Y3G4O#PL3E

                                2D              ; refresh

n1DD*p3ja4E[051Testing软件测试网b-N&ir D pQ

                                4H              ; retry

)fr-W&I;U051Testing软件测试网:HQ Q&S-Y.kf/]Q

                                6W              ; expiry

G|F)`p?.`051Testing软件测试网,W!` Gt9A2T3e `

                                1W )            ; minimum

u7bluA0

kDR wiB^a0 

;PhV?MR0

-VyG A&`-yQP0                  IN NS           test.sdpcop.com.

b;lxEy-A'T051Testing软件测试网 m[hG.FvX

56                IN PTR          test.sdpcop.com.51Testing软件测试网)]6D6A D+owX

51Testing软件测试网2M9y9`_x,}V

d.         配置/etc/named.conf文件,将需要解析的域名文件信息添加至此配置文件中。51Testing软件测试网 J0? n%fV%g+l

51Testing软件测试网U"i j[K%h0Jj

添加如下信息:

S2an~(?}6M051Testing软件测试网7ZuEc^5I\

zone "test.sdpcop.com" in {51Testing软件测试网.W F8V _Q+O[,\IZ-w)?s

51Testing软件测试网hjc8^(M)o

        type master;51Testing软件测试网6B[Xj{%^(i;r c

}1f O%bB&w P0        file "test.sdpcop.com.zone";51Testing软件测试网d;uP&{l0T

51Testing软件测试网D f biaAQ

};51Testing软件测试网fe-S5Vc

51Testing软件测试网Rt$u&pkX7ZR1L

zone "82.80.10.in-addr.arpa" in {51Testing软件测试网@$P X Z7a0w `1R

51Testing软件测试网7z?T_Tf9r0d|

        type master;51Testing软件测试网'm%xRY4Al$Sb

opID.?(o.}a1b0        file "10.80.82.zone";51Testing软件测试网] kF&g.d~3jN

x?{lP^ `0};51Testing软件测试网u4ngR\:j1Y

51Testing软件测试网V/zHRr0bHl!o

e.          配置/etc/resolv.conf文件,将此服务器设置为首选DNS服务器。51Testing软件测试网-c{3Ug+BA N GCS

51Testing软件测试网Z|j_LB

在文件中添加如下信息:

(~j?;L9j'Do/{051Testing软件测试网 Hb+?9} o3W{5y6N6yR

nameserver 10.80.82.5651Testing软件测试网AJ mr!])Hw#@

51Testing软件测试网$Z nz,r/J'\1c#Y

f.          执行rcnamed restart命令重启域名服务。51Testing软件测试网(B~u5~$K{l7X

51Testing软件测试网b*\ H1A)?

                                步骤 2     设置测试域服务器的首选DNS服务器为商用域服务器。

W!uh Y!k:I0

o,]xx}9X{(V0a.          以root用户登录测试域服务器。

lLfozE0

lj{Ok+r0b.         配置/etc/resolv.conf文件,将商用域服务器作为此服务器的首选DNS服务器。51Testing软件测试网*} Q)}rt2Q-q

C m.s,w?q0在文件中添加如下信息:

u[/av\b051Testing软件测试网'A0wi ~*]\

nameserver 10.80.82.5651Testing软件测试网f~c-u3e p

51Testing软件测试网5zb9K/I%e4rCy X

c.          执行rcnamed restart命令重启域名服务。

!|U"k V8u(H051Testing软件测试网f2dPz2^u6{g4Y:B

                                步骤 3     在商用域服务器中执行nslookup命令测试域名解析是否正确。51Testing软件测试网h y5g)?5ry

A'z*ZL"r7Z;q]0# nslookup a.sdpcop.com           商用子域名

(qN q*}Q;o#c0

.S+Rp/u o3oF.A0server:         10.80.82.56

@e1C;S(DX|:d051Testing软件测试网7Vd9_"L0P/_

Address:    10.80.82.56#53 51Testing软件测试网 Rt Q!m6r#L`&m'{

51Testing软件测试网VMF Vs:a I%u K

 51Testing软件测试网?R!|,G`-l ~

6DX6j6q9}Nh,p&p*W0Name:       a.sdpcop.com51Testing软件测试网'M)rI|!nAo

wv8u i~&n wU0Address:        10.80.82.56

p ].{Q:h}6m051Testing软件测试网B.G,U_ q

下面一行Address的IP地址表示域名解析后的IP地址,子域名解析到商用域服务器IP地址,表示解析正确。51Testing软件测试网6K[/O{ ` QW@*_

#|aG'i[wr,f0# nsklooup a.test.sdpcop.com     测试子域名51Testing软件测试网(?^%Cs8L

51Testing软件测试网~P%Y%GJ h,l

server:         10.80.82.5651Testing软件测试网 g[s0K"] g utE5b

51Testing软件测试网BHwt7g,s

Address:    10.80.82.56#53 

r+Xb#a8m(_k5|5U.OC2kN051Testing软件测试网'A6H/Eq Sv*m

 

/zN-w,F#D WZBnfZ.K {051Testing软件测试网 f!_9sRf9R

Name:       a.test.sdpcop.com51Testing软件测试网IJX V:b~

51Testing软件测试网 S1My#lki

Address:        10.114.153.230

t.R;[X:J jE0

:?)wK `!d8{0下面一行Address的IP地址表示域名解析后的IP地址,子域名解析到测试域服务器IP地址,表示解析正确。

&{\'rZSt#iU0

] l%\@ mqz$a0---结束

6V ^0ARzS0

C3@!tx%D-Cx3k0

u @m YV P0 51Testing软件测试网+c yq/up3j

51Testing软件测试网 ?!a^U$O({

u,r+g b9M`051Testing软件测试网 `rpVB6iFD

 51Testing软件测试网r$@3Z1i@T/K^@c

fa"o uC/V?;L0awk速成指南

-O*s/^o%wT051Testing软件测试网D;g6|\%W G

(

ci9ZIX\&d9F}2`051Testing软件测试网t:Dl(D(P S)M j

目  录Catalog

9D4nNk'fo'S051Testing软件测试网%D!T \5?Ak

1    前言... 5

|O?'q)a(jW2F051Testing软件测试网4v O OQ_"I

2    第一部分:入门... 5

)r6A~Di C.g6R2E#T051Testing软件测试网J'XW)gz:nXZ

2.1      第一个awk程序... 5

R,td1h*h7R$q2E@051Testing软件测试网3{ ^:wz0^A,f&_ Ot

2.2      常用变量... 5

tM/Ww u1_#_M051Testing软件测试网6jKy'{4{c4I p

2.3      表达式和运算符... 751Testing软件测试网3j(Z5Jy$Ghe jZ1u

51Testing软件测试网 p/{S ]!j\

2.4      字符串化变量... 8

:C"aVP l,TU:hJ k0

})B(A3H"Z{4H03    第二部分:提高... 8

;?[5Z m$]051Testing软件测试网NEw)?M5\

3.1      处理多行... 851Testing软件测试网I9}i;I,ko9YnL

z KI3T2k.p2X03.2      条件语句... 1051Testing软件测试网#e5wb8uM.p:pvL

51Testing软件测试网7j^\'x Xe9Mx}

3.3      循环语句... 1051Testing软件测试网3|6_b!\;E

51Testing软件测试网/I;n#sl H8b(h

3.4      数组... 1151Testing软件测试网@(tL"`1Ehg

UL2l i1b5ZH+@h8]04    第三部分:精通... 12

(r9X?G%x Z4T2A051Testing软件测试网wIy9x$gjR

4.1      格式化输出... 12

}yD&[2N7m)W)E^)}!X'o0

Mhx:_)d-R04.2      字符串函数... 1251Testing软件测试网5knd}C@

51Testing软件测试网#Z8H A}*F

 

Z ~#Qf S'Z?051Testing软件测试网#j;_)gP+Nr.^:X5C

51Testing软件测试网}5J Ji(gy:H*y6z
 51Testing软件测试网:xt `OfD,U u

51Testing软件测试网 { `"x2_+[

awk速成指南51Testing软件测试网+Mu6yy n7r

:K)MOrd k,|:l0关键词Key words:awk,编程,语言,Unix51Testing软件测试网0m g s'WSVDJ@

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

51Testing软件测试网1ua5V6O7|uVJ,B

缩略语清单List of abbreviations:

8O%bbb:] sw051Testing软件测试网2iiT1F}mj

Abbreviations缩略语51Testing软件测试网/|@ O2x#L*jlx1E

51Testing软件测试网6?8t&y5Sj%ui

Full spelling 英文全名

sY]:}|bm0

4N5yVMWN&G Q0Chinese explanation 中文解释51Testing软件测试网;{6^X3r8X

N G t hM\7h0 51Testing软件测试网` k"SM;ONtu

51Testing软件测试网-w? _8T%x^#b

 51Testing软件测试网k6?dZ!pw$E)pu

51Testing软件测试网u B$P}q

 

h;k7Wi6_P G\ e]P!@051Testing软件测试网 pO;bL:[*p8np

 51Testing软件测试网*Z6DF P,~4fOX

+k7wCF"\ ] ^Xl0 51Testing软件测试网QB%SdPy d

W u%cs[Z!Z`0 

%qE2m~0I;kf R{0

4gD3k0x%G6mZ0 51Testing软件测试网U.A:t:a3t

51Testing软件测试网#vUhT\CJ5b8D

 

g m0p1gv"I9X m0

ojx{_4L?0 51Testing软件测试网 [2|4K+eFL

51Testing软件测试网-Y1\f(v(Tr

 

YVRB9x)N0

V,c3H p-Qc8q!{:G+|$U0 

l_*_v4Wq'}0

p L5cH?vc#ff:\0 51Testing软件测试网 R;g4j%M4v2v v%GE

T#OA0k3f;p0K0a0 51Testing软件测试网5d4zl0@'az p

} \$J,~L0X2K.o0 

{i o4C5?fY051Testing软件测试网,~A(U.a4}{

51Testing软件测试网:s9Xt'p7{7a6r0c4@
 

6r#C|$c!e F01          前言51Testing软件测试网Sg!qo*E+vi4G(O

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

2          第一部分:入门 2.1    第一个awk程序51Testing软件测试网%Q'Rgq%_4v/K \"@(C}

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

d)W(b!Y/s051Testing软件测试网.s!HgY4[4sA.n_

Z:\D7e{p_2R0Hello world!51Testing软件测试网 V:aXoR

&qC6Xs!z_K"f|w051Testing软件测试网.sxoA}#W

6T~r Wl]m?F9T0在命令行中输入以下命令:

+{@] z6U%[%C,l `7I051Testing软件测试网kq}0f|m&?;N5D2q/}i

51Testing软件测试网8_kgL1N

$ awk '{ print }' hello.txt51Testing软件测试网_%IC}~9F(g/I

K jF$xxG0

TY(bp(?2h{0|0

z;Z+~@b\n n u0执行后hello.txt文件的内容显示在屏幕上。编写并且执行awk程序的方法很简单,如上所示,花括号内的是程序代码,后面的hello.txt为指定的输入文件。awk是一种行处理程序,执行awk时,它依次对输入文件中的每一行执行花括号中的代码,如上面的例子,就是对hello.txt中的每一行执行print命令。所有输出都发送到stdout,最后在屏幕上显示的结果为“Hello world!”。51Testing软件测试网&g8h uR o-k#n@

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

Ca"ea:KOx^0

h5?m6Kiy0

G/Cz%C/N i$e0{ print }51Testing软件测试网,dq*?ZNIf+IY\

51Testing软件测试网K'|da4]DCP#Ru{

51Testing软件测试网 D,mW+pI+C7NC8dT

51Testing软件测试网1C)jknf9K

然后通过如下方式执行:51Testing软件测试网%[? e q1X

IFB|4o8y!{051Testing软件测试网8m/C#~#h QK_+t+F

$ awk -f hello.awk hello.txt51Testing软件测试网&|7pk'R"F:x!i4B:}Z O

51Testing软件测试网7t(`fM_

51Testing软件测试网'o-t|$FIn C

$A(N rG+Z)l{#[0这种编写独立脚本文件的方式应用在多行、比较复杂的程序上,非常合适,而且,在后面你还将看到,这种方式还可以让你非常方便地使用附加awk功能。51Testing软件测试网+q:q8z}6e} I

2.2    常用变量

J@#S(J4f"[N7B0awk有自己的特殊变量集合。其中一些允许调整awk的运行方式,而其它变量可以被读取以收集关于输入的有用信息。下面列举出最基本的几个常用变量,并用例子一一说明用法。51Testing软件测试网w*K+f p1Uq

7t7a2p!Q~0Awk特殊变量51Testing软件测试网I1HzY!Sp(Uw

描述51Testing软件测试网FF R.ae

51Testing软件测试网|$|0Vy9@_)^1z K-U

51Testing软件测试网)GxGm%q

$number51Testing软件测试网x:V{u@z Y:\e i&H

51Testing软件测试网7d$K\(x,A-Ap|)DF

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

*PwH pSBQ AL051Testing软件测试网FYB)j|)~

FS

,` y{Q r051Testing软件测试网 rH)u |/kb8KP:gb5D

表示字段分隔符51Testing软件测试网FUL]K*^

z#GE(B wxu-U?&`0NF

$h.K sWm051Testing软件测试网0eC%?n6@*?+T8[ u!a

表示当前记录中的字段数量

k!J9wt,e)T/uW~'U0

!O\1n Hd4k$u0NR

U0s G!nI9I051Testing软件测试网r&b2z"CaX)or

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

7E\}(l)j0R0

t5OF0lq u3? |-d,y8T0

x0Tw q2})g0

&j oR#P ?B scrf0为了便于举例说明,在当前目录下生成一个历史话单文件bill(注意,是一行内容,中间没有换行符),其内容如下:

^$N|+\#x+W0

WO{Q4p"d!Lj051Testing软件测试网~F GC-P:r8tY2h:nt

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软件测试网W2k bep4@v

51Testing软件测试网%Hc%M#MQ6_0s4l ]

4429300,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软件测试网DI Sdw,Zw2Ky

fhu xe"V:p051Testing软件测试网,K"nyq(?.b

|A8x7e4PS'u F GS0我们可以使用$0变量将整个bill文件内容读出:51Testing软件测试网n`l.^/WDRm7q

,{b2iH0wo051Testing软件测试网uFc%y$dO#[K

$ awk '{ print $0 }' bill51Testing软件测试网+v_CdH5d&R*ci

$q#X!},VdA0

`3@T sN#Kh0

+v!N%ZF;NEf2O#g0可以看出,在awk中,print和print $0的作用完全一样。51Testing软件测试网e v,yOx#L:J

51Testing软件测试网tuM]#p*C?^VP

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

9Il+Q E7\7F0

m_j4SC051Testing软件测试网)a:k [:} E%D X

$ awk -F"," '{ print $3,$4 }' bill51Testing软件测试网E u$E`D k

51Testing软件测试网 bv2iq|4? M~h

51Testing软件测试网 g"Pa6y4O?h IL

51Testing软件测试网3v:Mk~-Hc9p(b

上例中,在调用awk时,使用-F选项来指定","作为字段分隔符。awk处理后打印出主叫号码字段和被叫号码字段。而且,你还可以在字段中插入字符,比如:51Testing软件测试网*Kl Gpv `,g@

x \"~ w#`#Y#g9q051Testing软件测试网z(M3hqd(ZmA

$ awk -F"," '{ print "OrgAddr: "$3, "\tDestAddr: "$4 }' bill51Testing软件测试网:rVmQ7Q`T

dY5jS7f051Testing软件测试网f-]8R9x)QV

51Testing软件测试网7]?!a$mPif

以下是该脚本输出:51Testing软件测试网8i#LR0jc!j

[jd f} ~V&]_051Testing软件测试网%S0Na ew5FD d7}

OrgAddr: 8613902700001  DestAddr: 861390270000251Testing软件测试网6K(k b]e`

8n}h&}R9Y0OrgAddr: 8613902700001  DestAddr: 8613902700003

!m7vM7m,OO%b4TS*~Y5`051Testing软件测试网} mbM S

X8O9s2u.bi3p0

`'ht)d\+G7_:p'K/v0以上命令中,我们是通过-F选项来指定字段分隔符的。如果我们使用的是脚本文件,则就要用到FS变量来设置字段分隔符。编写脚本文件bill.awk如下:51Testing软件测试网 \_ z7a2q3VOy

51Testing软件测试网Y2JkX3aU U

KG3j\)mFbj0BEGIN {

:D3]^Zj/SI_bv051Testing软件测试网balx"X[

    FS=","

5qL(Rb5{`+Z051Testing软件测试网K,F/b ^'](^s1PyF

}

[ xD-?AAbe0f051Testing软件测试网[a%d/^6v U"`:u0{

 51Testing软件测试网H IY9K,w qlr

&g7CdFZ-q9C0{ print "OrgAddr: "$3, "\tDestAddr: "$4 }51Testing软件测试网UbG5M@9c%FsM

/Y;h^ wXJN5P0

0uf(HfY:x\0

$P{&azAg4z{!l'p7U0建议最好用脚本文件,这样方便日后重复利用,也方便修改。

PEzy3N7cPj0

j&Nx;Oe$QF0FS值并没有被限制为单一字符,可以通过指定任意长度的字符模式,将它设置成正则表达式。如果正在处理由一个或多个tab分隔的字段,可以按以下方式设置FS:51Testing软件测试网6x4\;Zt#Q2Xl9v4Z^

X&h;QS)e*k051Testing软件测试网zrrT9|'Q

FS="\t+"51Testing软件测试网#Do;pb:n.wu X

51Testing软件测试网#gF3LWg7oR

51Testing软件测试网P QWtl6` T9xG(^

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

51Testing软件测试网,M UM)dhLJ D

awk还提供了另一个特殊块,叫作END块。awk在处理了输入文件中的所有行之后执行这个块。通常,END块用于执行最终计算或打印应该出现在输出流结尾的摘要信息。51Testing软件测试网!Yi w:XG*i/w*C

51Testing软件测试网 FYW"e|9WC ct q)a

NF变量,也叫做“字段数量”变量。awk会自动将该变量设置成当前记录中的字段数量。可以使用NF变量来只显示某些输入行:

N:B5jy;UY5Wr0

Q ?!@ p&t#~\051Testing软件测试网VL)gy*S|)G-Q&Q~

NF == 3 { print $1,$2,$3 }51Testing软件测试网F*@EI6x9C U

51Testing软件测试网Y| ]xt pe

51Testing软件测试网u7X^m ^.f5p#l+c

51Testing软件测试网!D1sA P^7o\Bb\

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

0J'O_0p5]k C8v C F0

"s-hC4R4ckO0

j)yX!U9r0(NR < 10 ) || (NR > 100) { print "We are on record number 1-9 or 101+" }51Testing软件测试网r&CZs^*I8f

51Testing软件测试网7Yv8e9K&`(P.dD;jD

8z0K-HsQ| Z051Testing软件测试网^f z Q%B7` hT

在本文的第二部分我们还会讨论两个特别有用的特殊变量。51Testing软件测试网/\'WW7DN&K:h1{

2.3    表达式和运算符51Testing软件测试网4K)D~:` n

awk 允许使用正则表达式,根据正则表达式是否匹配当前行来选择执行独立代码块。以下示例脚本只输出bill中包含字符序列8613902700003的那些行:51Testing软件测试网+L*Qz6Y+l0L#I

&`n Z.C5A+Gaz0

b)KOQ;F9r8J9re0$ awk '/8613902700003/ { print }' bill51Testing软件测试网\%pd&s z&xHs

51Testing软件测试网[!u^Z(p rC{B

ZcZb&y:@0

'`8iOLR0当然,可以使用更复杂的正则表达式:

,K/Pm}uWD,w0

;e'y$HMn`s A}0

.G&Lt's@:q*Q f0/[0-9]*/ { print }51Testing软件测试网U@u DI#y*R O

`)h7qh+miq051Testing软件测试网6~${Q-@_@+w

51Testing软件测试网kjD!Z/]'y X(A

下面列出正则表达式元字符:51Testing软件测试网6Ttx5TU

51Testing软件测试网gE0D.wDP

字符

X!d'M"j*z j@(U0描述51Testing软件测试网KKH x7ez\c%h

t.\#wSN%h0

XM"Os3V?&ux0.51Testing软件测试网;~+I)H t7o'u kU

51Testing软件测试网b|?n.]7}$g]B

可代替除一行之外的任何单个字符51Testing软件测试网V}E qn @7`

,S W!|^1E0X?5fQ0*51Testing软件测试网 ] lwN"M9g5b-V

51Testing软件测试网.SH @+TZ wB

可代替零个或多个在它前面出现的字符51Testing软件测试网+P:K$zV-ZV

;ke'_r-~a7ID.[(F0[chars]51Testing软件测试网(FjI!EoBac

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

51Testing软件测试网K%N1G d6q

^51Testing软件测试网)nk;T&OPDRu O%?-N

:y8e+Oux J0匹配一行的开头

O/v0t N#v-m F051Testing软件测试网 { ~m2y[0o/vLT

$

YQ0u0B}s"R0

1B-LT*V3n/L4qD;JF0匹配一行的结尾51Testing软件测试网8Q/SsDkXE

H eFR]s+@3V0\

HvwT/Rh,Q051Testing软件测试网Wq"v7x/w oU$L!pAN

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

&j$iAS6c6Hc!Px0

y$x_:x%n#p*\m6gS051Testing软件测试网4?"Bv_l,u WY]

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

8n)l*K-e _;K1o$lN4x0

l.m%e~4Se+U*W [051Testing软件测试网`r f$C5o m o

$4 == "8613902700003" { print "OrgAddr: "$3, "\tDestAddr: "$4 }

U2h+n:y qP6h051Testing软件测试网1r8Z|c{e

51Testing软件测试网#Yyh"^*q}W EE

51Testing软件测试网$BPq;N:xSQ3J

注意,代码块前的布尔表达式必须与代码块在同一行上。51Testing软件测试网^Zw.xOc

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

YP&NgG2xN0o0

Ho9[s|FO_051Testing软件测试网0` e#@/w`.I6T{Y

$4 ~ /8613902700003/ { print "OrgAddr: "$3, "\tDestAddr: "$4 }51Testing软件测试网)b*p{$?n [B

A c\4{1[0

`!^i(]i!H5R051Testing软件测试网 UqUc!`

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

$_)K*{UsfS&Z051Testing软件测试网*Eew[h8\

51Testing软件测试网b&N0nL9dp g0q$i

( $3 == "8613902700001" ) && ( $4 == "8613902700003" ) { print }

A)M0e ~Gu Bw0

YdLu$rif]051Testing软件测试网c!ZI `:f1i@a

51Testing软件测试网8S|5D d]-P['kj)F^*|

awk的另一个优点是它有完整的数学运算符集合。除了标准的加、减、乘、除,awk还允许使用指数运算符"^"、模运算符"%"和其它许多从C语言中借入的易于使用的赋值操作符。51Testing软件测试网|:\'atO? b5l1i*S

,ahXOu1HDP0这些运算符包括前后加减(i++、--j)、加/减/乘/除赋值运算符(a+=3、b*=2、c/=2.2、d-=6.2)。不仅如此,还有易于使用的模/指数赋值运算符(a^=2、b%=4)。

Qf]U?9m02.4    字符串化变量

-R:l:k*YF LtL0awk变量“字符串化”是指所有awk变量在内部都是按字符串形式存储的。而且只要变量包含有效数字字符串,就可以对它执行数学操作,awk会自动处理字符串到数字的转换步骤。请看以下这个示例:

8f!p Wc!dquPhj6V0

*zEOLuMd0w0}051Testing软件测试网}.KP tE%y!G*M

BEGIN   { x="0" }

j*KTC3H051Testing软件测试网r+Zx"P,[

/^$/    { x=x+1 }

8gy ~?.z f0

)m/rm ev-F)A%s0END     { print "I found " x " blank lines. :)" }

{[@7E8e0jRV051Testing软件测试网4Z`z E{2Po`5m

51Testing软件测试网0I};]G0a(y

51Testing软件测试网6m{(c0X8g q

这个例子的功能是计算文件中空白行的数量,^$表示空行。

}#W B]7TU;l1^051Testing软件测试网 Lr$n~S!N3Ol+X

如果做一个小实验,就可以发现如果某个特定变量不包含有效数字,awk在对数学表达式求值时会将该变量当作数字0处理。

)\2n z#GNa03          第二部分:提高 3.1    处理多行51Testing软件测试网+Qej fuO?}

在这一节里,顺带着讲一下三个特别的变量:

o"y1J*y;RC(wZ o051Testing软件测试网8E-`H b'N9['^

Awk特殊变量51Testing软件测试网m x3yg$kS.|.R(~&w$o

描述

F^Lq'MY&O"f0

!h2~ {d:mFp051Testing软件测试网D }9`#J9@:M*AYv/z7h

RS51Testing软件测试网x0S#CowR

51Testing软件测试网-V*T&m2j)eK:iB7u"j

表示记录分隔符51Testing软件测试网 zwT`E!v

51Testing软件测试网"mw1k%xR8W ^ ^W`e

OFS

T#_J1f9| Q \b;J051Testing软件测试网[ k*Eo"h

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

w%IIki{J:K051Testing软件测试网4~}!N?gJf;[Y

ORS51Testing软件测试网?d7M rx.?Cm `

51Testing软件测试网2yzzsBC$iC#^(Z

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

.?:dA9nsRM0

"`![!lU0EM3Xi051Testing软件测试网(@ou'Db6o

51Testing软件测试网dq8`Mq

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

51Testing软件测试网 L A_!LIO?

为了便于讨论,我们依然首先在当前目录下生成一个通讯录文件address,其内容如下:51Testing软件测试网$O|R#J| Z7BX%Z

51Testing软件测试网1tMdu+lh2[r F

51Testing软件测试网|^Z,^:MJp

zhangsan51Testing软件测试网AP g+qF^k Gqq

51Testing软件测试网]$J.Uf;od0F7K

13712345678

B7s'E4J%Nm9R-|0

7r%N i#J?!]v(W0zhs@hotmail.com51Testing软件测试网6[ r'l'z4_+`6w7h

51Testing软件测试网.H5V4Q;g7`CX

 

!I*|2d c+h!Pjy0

C/[4w{9e N0lisi

a*[9D4{v bh051Testing软件测试网2O*V$w6c'y"tp2}}

13012345678

rax3Hce1]MnRc0

1MVOQ*~g6M?0ls@21cn.com51Testing软件测试网 f;OjLy)a K-u,h"T:ah4o

51Testing软件测试网T bbbd!U!IrX#L6~

(W;O wxh6p5d051Testing软件测试网*o%Z-O }a?+G

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

y)v'Y X8z/Z)f-]0

3z7Y/q3p(W.qvD3q0

h.S6EV|}*w0BEGIN {

!pN T6KT F!]-jj;N051Testing软件测试网2p#t w!Z6Xw%f9W

    FS="\n"

)\$i6U U4no){ L0

}1d'yR-A"b ?8A0    RS=""51Testing软件测试网%K$t+MilSr

51Testing软件测试网9ik4y4\8~p(Z

}51Testing软件测试网 II7V4^8x1Z

GQ1qyp"t3d0Mt0 51Testing软件测试网)F|Fm|F

51Testing软件测试网F T!JP3[J

{

;I4NV]U0

C-? ])MR Ug5g$?*N~0    print $1 ", " $2 ", " $351Testing软件测试网}C&T P@0\

3n ~@T@Io j%gb)M0}

Z+Hn9DY?0

8H8~O N)m0

t_:Di ZA051Testing软件测试网X L]1BFe

此代码将产生以下输出:51Testing软件测试网s/B-KkIc]

/P2t+dj,h.t,jN0

un3F1ZRc|V0zhangsan, 13712345678, zhs@hotmail.com51Testing软件测试网#X ME Y.xQ Ah

51Testing软件测试网 }/x(m?` NS(NDxO$]

lisi, 13012345678, ls@21cn.com

~4}R'twz&V0

n-\/eB*oy|0S%~#qC0

,@D {0S5u3[0

/NUP8Z NK0在上面例子中,为了在三个字段之间插入一个逗号和空格,使用了", "。这个方法虽然有用,但比较难看。其实我们还有更好的方法,那就是设置变量OFS(输出字段分隔符)。OFS缺省情况下被设置成" "(单个空格)。使用如下脚本可以达到上面例子同样的效果:

[6f`g-y'V!B051Testing软件测试网&y^&z&\ Rs[

H;_N:^7KY6~9Sq0BEGIN {

E!SaI3y d!?;c$}e0

G#F1@A7}Zp0    FS="\n"

9a;zw.hwD6B:I!c0

3\.Q@f wk8@i0    RS=""

y(~~-G7|V0

S5\fEA9{3A0    FS=", "

{^v%nr:~L051Testing软件测试网U;i!~ ?w6V5bX%L.a

}

$eIm(Nq)QC_ SDI0

U/enm7EF0 51Testing软件测试网hGNFVG9U

51Testing软件测试网j#@L9?a

{51Testing软件测试网6i ]*O%XL K:@%F!]-x6H

(D ~8NjUlp0    print $1, $2, $3

T-B)D j-Oco$Lq,lM1AB051Testing软件测试网 yJ+YPp&i6}

}51Testing软件测试网*rFkoQD$?4B

51Testing软件测试网-\ HSV4aH-U _6e

51Testing软件测试网|.n P7w!g{1p {

/f} sk4cUq \G0awk还有一个特殊变量ORS(输出记录分隔符)。ORS缺省情况下被设置成"\n",如果我们将其设为"\n\n",就可以使输出记录的间隔翻倍。例子就不举了,大家可以自己试试。个空格分隔记录(而不换行),将ORS设置成" "。51Testing软件测试网j+T#}h7X6@3~

51Testing软件测试网9T9kq"oK)y!z

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

b5pvGB d M d#A051Testing软件测试网5X!?dl7U"^

51Testing软件测试网V*r/@HM9H4p u+W

wangwu51Testing软件测试网)s$`W:a0V hI _

51Testing软件测试网Q{Ly \%PD"?v

13512345678

&L4J[oF;A0

x7e/T(S(d;T gBJ0ww@163.com

$Sqvs hV*g)pin051Testing软件测试网#h(Tu6]|.m

wuhan, hubei51Testing软件测试网D+Kfp&Z9]SRFN q7n(l

51Testing软件测试网\k Q|o

51Testing软件测试网#E1_JA%_ KY5q

3L;fJ,\O8oV0要处理这种情况,代码最好考虑每个记录的字段数量,并依次打印每个记录。以下就是修正的代码:51Testing软件测试网.T!P6tm(SO

!X@v,hy.xuC'z@$s051Testing软件测试网_0cL3x"^

BEGIN {

X fu za}t:jFa051Testing软件测试网rfcGm V2Xx

    FS="\n"

.\*ifg7o3m)h051Testing软件测试网V[ NU^sc)uz

    RS=""51Testing软件测试网 U/An [R

.z uQztiRWR.X0    RS=""51Testing软件测试网RX r:f Aw9?K;y(~'J

51Testing软件测试网K1bX+PvB-U C

}

K&~R@4L051Testing软件测试网} rm5yzxG

 51Testing软件测试网f'd1UcnF0n6\

O*O+BG(xO G0

Z2wET4y.g0

_7j,WO1~0        x=1

7`? h5a2p6my l,n Z,V0

Qg2m%RQQ;]Xzf0        while ( x<NF ) {51Testing软件测试网3@9V euQdE

+rD;X$LI-j0                print $x "\t"

ibWE6a&Z I6ZE+i051Testing软件测试网*o.mS#U"Zep

                x++51Testing软件测试网$P+k1A'KPS$Ku

Z4oE)h$ZD0        }

?H4p/C4ho051Testing软件测试网.~;zj%{2y0Bb$G(J

        print $NF "\n"51Testing软件测试网;Q%X6F{s/~

51Testing软件测试网I;Nn wY y

}51Testing软件测试网S Q!d`e6R0s2j{

51Testing软件测试网&{i hs9P W[L

51Testing软件测试网8I z.Is.\wI

51Testing软件测试网:f}G Q5W!@ j

程序输出如下:

(az2m2kOS051Testing软件测试网;^ m(p h*B

O"HM$ho.q0wangwu  13512345678     ww@163.com      wuhan, hubei

0Aq+HL#\051Testing软件测试网 V%Qr%S$g)H

[Q#`mbb^03.2    条件语句51Testing软件测试网'fE#xU:e{l

awk的if语句类似于C语言的if语句,没什么好说的,举一个例子吧:51Testing软件测试网4n['d h&iq;x

YP/wUo d0

EEa?l,Y;L_{0{51Testing软件测试网1r l;f^$N9wz&K

"E*p5S yg,CET+}0    if ( $1 == "foo" ) {

*xgEI L5Qj3KUO051Testing软件测试网m8p5aZl:e

        if ( $2 == "foo" ) {51Testing软件测试网VTwC*o6v7h

#D1tkJx8\O0l0            print "uno"51Testing软件测试网Y[7M Ro{+D8i*l

51Testing软件测试网8v @ B$VH1ar!m

        } else {51Testing软件测试网?H OD8F'Tz{

S.z&P w7t9rz0            print "one"51Testing软件测试网 |^;O7?-M2n#_PZ8h

K8^L5ETkER0        }

%A-e1PnMG7V0

QS%m5|3veiv0    } else if ($1 == "bar" ) {51Testing软件测试网}w tw-j E

Q+e9b y!};D0        print "two"

L+C$U(n)n5J4U7O:IAs051Testing软件测试网$} S:gi^3Dpc

    } else {51Testing软件测试网}!JEM1cy?

u#d7]p/F0^0        print "three"

2jW)ZO2J8~t0

%F*T9?eH]| qK0    }

Vl8}.h w/_0

x u)m:p:` | vi+z|0}51Testing软件测试网B&nl9W/B'`J+f

51Testing软件测试网*hkL`Qlp

51Testing软件测试网Y e!cg1^,g

3.3    循环语句

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

(a-v|,oy(A051Testing软件测试网F F0a-S(q2R)C{t#}

do...while 示例51Testing软件测试网3S8[k-d hq|'eY

51Testing软件测试网2E*B R:h+g;mfX|9i

51Testing软件测试网Z(ivv'FY9N:p%rac+i/h

{51Testing软件测试网f6Dm-h f2o]

zM6K,Vv?W0    count=151Testing软件测试网Y/d0@ PUS:qg

3]6Pn J-B0    do {

Mg{.{6u051Testing软件测试网O? qm1d'eb

        print "I get printed at least once no matter what"51Testing软件测试网.HA${*AJ5ii

x'TL;P.^/xc)}0    } while ( count != 1 )

D&tqC(z} Q051Testing软件测试网_5w"L3E3Vw!UKg b

}

c9vdB%H/q i0

c A+n1`|!MC,s0

O#L iHOH2J7CF051Testing软件测试网 j*e*gub8M^,Y l

for 循环

$T!@U?A0

0B-s*x%C+K4hih.v0也等同于C语言的for循环:51Testing软件测试网4x/F0f2l]/qa S/P%e

\e!A#?XN/uC051Testing软件测试网(Xt|Q#Wc[,@

for ( x = 1; x <= 4; x++ ) {51Testing软件测试网#k v&b]ZJ YUR

51Testing软件测试网/~(c*X*C7d2MlG2? j

    print "iteration",x

"{9p]\"bJL051Testing软件测试网W"xqi4sY,X6rC`P

}51Testing软件测试网qUE%`Je.r

51Testing软件测试网XK!ZQ%s-XA:O;ma8{

51Testing软件测试网!eZ6P;V(m,U U

51Testing软件测试网Rk&|js*X9p5Vzg

break 和 continue

0g[;^rr,D051Testing软件测试网@+uDyQ:{6p:i ]

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

3.4    数组

-V!nz5Xo8|0在awk中,数组下标通常从1开始,而不是0:51Testing软件测试网n*]0B-{ x4g!EN|.~u

51Testing软件测试网-c;\%]^!aQ

iS|)sjHE,w0myarray[1]="jim"51Testing软件测试网!q*S H@4bYBs

51Testing软件测试网g5o%l@*aI4_r!c

myarray[2]=45651Testing软件测试网vy X:X'e4{1KC

3L W\`+UxK0

k0sx6d7V^051Testing软件测试网OV;`)N e0\ } ]l

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

C$OGR&BOAO8Rg"b051Testing软件测试网:`%nlV$\!yuS

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

}AbC/nD1O-~ C0

)\)uPw d*fN/v051Testing软件测试网z,~ L&rgp

for ( x in myarray ) {

k5U3l:p!Fsy0

Cm)\BFKv5N0    print myarray[x]

7]@p%iY051Testing软件测试网O*dx;h5N1u

}

E$D Nw IX&OD0

wV;];m+B#e*[051Testing软件测试网 a!H8~+~Qb

#}$G2s(SZuJ)c;S1Z0但是这个方法有一个缺点——当awk在数组下标之间轮转时,它不会依照任何特定的顺序。那就意味着我们不能知道以上代码的输出是:51Testing软件测试网 L1MrQnp.b X

$`hcx"\0

_4qnQ"|6w4b3m0jim51Testing软件测试网 dBFt!ot,W1[m

51Testing软件测试网?l3n)KO zL?

45651Testing软件测试网/` D{Y ND

2szOzbk051Testing软件测试网 _'iifu7G q

51Testing软件测试网:g{!jo#^ t dg

还是51Testing软件测试网)H3^,[E TXD

51Testing软件测试网&T{I#]j

51Testing软件测试网AzpZ(QOE;UM4?

456

em F)K*vq051Testing软件测试网z|3T.u*S,yZ_

jim

'Mhn8eIn0W051Testing软件测试网1j8G1`(rU

51Testing软件测试网(EF:h ~2Z A'k R

51Testing软件测试网(](z I LUe@

awk数组中还可以使用字符串下标,其实,不管你使用的下标是字符串还是数字,awk在幕后还将其认为是字符串下标。举例如下:51Testing软件测试网CO9O aXa)p

-og$o R~XS0代码一:51Testing软件测试网4[,XE u$}/U Wn

51Testing软件测试网,E1q5n t5Sq

&u5e4I8QO3ee%to0myarr["1"]="China"

F |` ~0y0

JWs;h/T/n8S0print myarr["1"]

1qI|{VGK1}'Z0

3J6| Ab4k'[)w0

![5D|(BP0

*_+P XFh0代码二:

{O.X A1p0

c4m1e!Y R~`0

m8UGV o3I8s0myarr["1"]="Mr. Whipple"51Testing软件测试网$qcLX0F b5Q5\

|"|E I U#Oy p0print myarr[1]51Testing软件测试网S lF/M"V8To*{[

51Testing软件测试网j|a%] VNW2?

51Testing软件测试网P UPY+B1d)k&I(YL

51Testing软件测试网%a'i(}#q[%M4r)P\

代码三:51Testing软件测试网 L!Q ~1N1H Bl

i n;|0?M1TkH~0

3SK E K,U8l yN@2E c"s0myarr["name"]="Mr. Whipple"51Testing软件测试网*^+]z"b'L

+CN"Z JT"_)Mn S)r#W0print myarr["name"]

2F%xA7} r&J2UI0

KeO O1XL8k Ki051Testing软件测试网0D2} @t O,i

51Testing软件测试网"vJ G[5@7A!HRn

它们都将打印 "China"!

`!f#@xm"VS051Testing软件测试网t,C6f.K;@:KtE[

删除数组元素使用delete,举例如下:51Testing软件测试网z AOWH PX

51Testing软件测试网 h`_S,F I j \3~q

51Testing软件测试网Aw"C!_(N4U

delete fooarray[1]51Testing软件测试网(\ ToL$rD

51Testing软件测试网%Pzykk

51Testing软件测试网0C:Pn7C|'t w

A7dgn*O4f3W,}0另外,如果想要查看是否存在某个特定数组元素,可以使用特殊的"in"布尔运算符,如下所示:51Testing软件测试网R!_F c+PK

51Testing软件测试网 DFf2H\p|5c7Z

51Testing软件测试网`F-_jdP,i(@:L

if ( 1 in fooarray ) {51Testing软件测试网,? z K0U+@ d3`

51Testing软件测试网.m~G2{.]v,S7D3a

    print "It's there."

1cu2O SmM8{051Testing软件测试网4D }w!L*gA6_

} else {51Testing软件测试网m#{J |;c"T;VN,j

nNm._M6Ng1o1z0    print "Can't find it."51Testing软件测试网KwY_z

;^/Ir5NZ_GEBq4Z&O0}51Testing软件测试网 G`\ m5j"K

51Testing软件测试网*Sw B x| i}h

OL:|j:j04          第三部分:精通 4.1    格式化输出

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

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

r6v!zO+}-u"K"S0

i4t3d2@?wv;VW0

k)Q]Z4a ?[I/g0x=151Testing软件测试网E1X)v`(r*GN

51Testing软件测试网a%X;{)T2~~F

b="foo"

9YO;RQ6? M#|](h051Testing软件测试网^4mhM?)R

printf("%s got a %d on the last test\n","Jim",83)51Testing软件测试网*x h f4f'^*ep0T3m-\

51Testing软件测试网3x)DQApIyTL2T,H4u

myout=("%s-%d",b,x)51Testing软件测试网*|&X"o O8W!Q E$Q/`D[

J?F2K'P8v|0print myout51Testing软件测试网 Y*T.Usu,@T@6hh

51Testing软件测试网)K\$?JC}5c`F^

51Testing软件测试网;N,|(|'H\V

51Testing软件测试网5Hv(PQ/N

此代码将打印:

p"Wif0Q;_"d} e&j0

Mke _B:_5dT051Testing软件测试网 }E:\K~+h!n

Jim got a 83 on the last test51Testing软件测试网4GCeEM1f5d7L!T

kW`&BK;mP0foo-1

#nSu|OVJ&h)F1z3R0

P e8wW1[ B T051Testing软件测试网1P'qZEM r

4.2    字符串函数

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

5I+b dT;Bc(Ow*B051Testing软件测试网d)Py)s/M O9F9k

`@ ~ LT$}0mystring="How are you doing today?"51Testing软件测试网6t7`:?,lSZ

51Testing软件测试网 nzBH.xj;C

print mystring[3]

-f _4{O-}K0

7d/xG GC051Testing软件测试网:Tdw y j'y

51Testing软件测试网T!b!y?#{_4B t

将会接收到一个错误,如下所示:51Testing软件测试网)x/C I"|la5C_Fy'?

e/x-X\c-~"~8a |0

2^yj6uF7u*`0awk: string.gawk:59: fatal: attempt to use scalar as array51Testing软件测试网.t.]3wrxc

@7z9i,^;~2[R0

Nl[j}BKj!E UM0

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

~^ [ ~V~ {051Testing软件测试网I*Z#| hj$?%P

字符串函数51Testing软件测试网9t-m2Y(x9i5b3|u

描述

Z:S1t:]F Rs jbw'z0

_O3M-zcO;p.xQ0

?X I+r!LBN!f8ni0length()

)h0}'gs%`[G051Testing软件测试网9a:Xc+DL\'s%w

返回字符串的长度

!k$Ra!H[ m~M"U3D0

*R-zA'z_2{8y,@v0index()

:D5X;pT:w)ZZ)^xm051Testing软件测试网#um]%O}DH

返回子字符串在另一个字符串中出现的位置51Testing软件测试网+V:l,nv6][F

51Testing软件测试网D%zwc'l%F$]2~K7i0|

tolower()

4lQkf&_(i7~!b0

,I[vE7y)Z;lD0返回字符串并且将所有字符转换成小写51Testing软件测试网d}&YUL.R

` d!i.B@@0toupper()51Testing软件测试网9w&BF N7M+A5U@p

z#{-c!Y;p?0返回字符串并且将所有字符转换成大写

}6@+TB$O-w BV051Testing软件测试网U'q&?q6J(c+_6a(N$u

substr()51Testing软件测试网3KGe7{E

51Testing软件测试网^TV+z$g)\

返回从字符串中选择的子串

jh3s9O-G8WA.i\051Testing软件测试网'_'z ]T&w q-Oc2h

match()

t t-a2dMM0X051Testing软件测试网"kM g&M ke

返回子字符串在另一个字符串中出现的位置。它与index()的区别在于它并不搜索子串,它搜索的是正则表达式。

pr LcQ:g'U'L7P051Testing软件测试网$Tz _ JEsF |3o

sub()

.d~!fYc[$k0

Tk"cG1NA0替换匹配的第一个字符序列,并返回整个字符串51Testing软件测试网l ye1iJAuM^

51Testing软件测试网 W%XAPP?{

gsub()

7e.Q vW l0C3z0

-OGH$X'Yl0替换匹配的全部字符序列,并返回整个字符串51Testing软件测试网 CA}r A1L$Jv

n{| oh K],`!g0split()51Testing软件测试网7zX6q[ yz!}#b{

51Testing软件测试网XHN-xa/D/i [

分割字符串,并将各部分放到使用整数下标的数组中51Testing软件测试网Cb Yp0H6J9V

Qfq:zc0

BD b6N*W*u0

4{+@(X0Vqd%ld @A0length()返回字符串的长度,例子如下:51Testing软件测试网0o1D6Mo#M:A

51Testing软件测试网)Hb f\}*u }

51Testing软件测试网N Q5Xo8S+G$_lB_Q

print length(mystring)51Testing软件测试网`:X SuA|(Wx

X!Q,T^5L[2j0@H0

+M*H;g_)D0

?`K!y2u4Wg _;R0index()返回子字符串在另一个字符串中出现的位置,如果没有找到该字符串则返回0,例子如下:

/kT$s1g\H051Testing软件测试网 w7C#@ U |8g%n6Y `-h

51Testing软件测试网9N'm wD.r `

print index(mystring,"you")51Testing软件测试网Gg?UX{|c

'H$C4B%Y'L0

Z\Sn2E7bah0

[ N4c\Zrw0tolower()和toupper()返回字符串并且将所有字符分别转换成小写或大写。注意,tolower()和toupper()返回新的字符串,不会修改原来的字符串。例子如下:51Testing软件测试网Z v8eGgP5mkc

51Testing软件测试网^z3Mzh,l

51Testing软件测试网 ohl:` ?(dbsq1`

print tolower(mystring)51Testing软件测试网fSI1oGt0q QDQ

$ff4v2ac-|1is6b8C0print toupper(mystring)

`mMfQ,L051Testing软件测试网{Gf3zF G2lw5?

51Testing软件测试网5oC)C"y dU5L

7_ FS8g \@0WS0使用substr()可以从字符串中选择子串。以下是substr()的调用方法:

V$?r;~F8sI%k:c!A051Testing软件测试网4?x%w O,p

kf,Kux7z'n HC)o|0mysub=substr(mystring,startpos,maxlen)

M&m@1X%h+X ^M0

tjA x-T6xh051Testing软件测试网1uWOzfm)I7p(r

51Testing软件测试网S%]V3[z#J

以下是一个示例:

#FvnBh&xQ0

P g3~ fJO0

? szAZ+X7z0print substr(mystring,9,3)

,Dx(WHI gl051Testing软件测试网`$P M'B _k?(]+z

51Testing软件测试网h ],ZW iYm S

51Testing软件测试网"sb Alw~"u

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

)eKw4i"S n8K051Testing软件测试网#i uy[JpTJ

&U/YAE8e"j/jA u0print match(mystring,/you/), RSTART, RLENGTH51Testing软件测试网JEW ^(boW1a'H {

51Testing软件测试网:|*o q!@[/ZF

G#O0^M|4TGj(T,Y051Testing软件测试网)Zh c#~ Z.p!o7Yk

sub()和gsub()是两个字符串替换函数。sub()的调用方法如下:51Testing软件测试网7Bq)vw._k g U7J

51Testing软件测试网'C)}#Mp__a6q

51Testing软件测试网;A_J:ILk

sub(regexp,replstring,mystring)

_5fw5U xg0

+~d o%w;Sn"aIo051Testing软件测试网!t])o#PH]

pG$qA7F%[ X-z6w0调用sub()时,它将在mystring中匹配regexp的第一个字符序列,并且用replstring替换该序列。gsub()与sub()的唯一的区别是sub()替换第一个regexp匹配(如果有的话),gsub()则执行全局替换,换出字符串中的所有匹配。举例如下:51Testing软件测试网+@:@t N6J9jJ Ol

51Testing软件测试网UNBpne0z:e.~H

51Testing软件测试网*XY _-ut

sub(/o/,"O",mystring)

c O2Br3@)B0

"Q7iv`aX0print mystring

)U\Cv ^w;G2T c051Testing软件测试网*W\p(A_t

mystring="How are you doing today?"

&ZIC6R(hA? St2P0

T txmOt.s?0gsub(/o/,"O",mystring)

,w W D5mw\sg_0

:?1n y9k P B y'nz0print mystring

3| |{V T t3_)p0

Q m*I_ p7p!UD1xV051Testing软件测试网8N-a x2i4s.f"?

5Xu%MfK'o3R0其输出结果如下:

4`:z,w|f~[E0

:ts#EA4[(h5K%LCLmJ051Testing软件测试网.qw+M0]g0_f

HOw are you doing today?

?;s1dm X:i0

;npA1O0jx-a j0HOw are yOu dOing tOday?

h"?#[(sw%I0

QIYU T3wAr0

:` zK&|s0M"RK0

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

Azd9d#BxiUa u051Testing软件测试网M*S-|s}O-AN p

5L [ gpln0numelements=split("Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec",mymonths,",")

4X"l2b2z,nl0[zS0

*~dKG3u#F^)y&xH0print mymonths[1],mymonths[numelements]

9bUI?3kx0sX0

LB y"U7ZQ)O:]0

)t)_{Wd051Testing软件测试网$Iq:@.EP$U

其输出如下:

4}3BtS$]o)~0

'HC2JO,D051Testing软件测试网*s%]9nb-K@ H

Jan Dec51Testing软件测试网6b${ SEk"g:t

3uO&IVA$i2{7bE0zx;I#?0

.^ {;d _0Z x051Testing软件测试网qP"|9S[}3|*|

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

dA*xq7s v1j0

Ck p^(K:f @0

df"R l_^ yj2{0{

?pP oRl0

V7v~;Pfu/a2@1l0    print length()51Testing软件测试网P.s g)J-y"xg!h\$q9_

51Testing软件测试网,P9^g]s*\3Y

}

5bB'YNN/m]0

3K`3n#O+vKKC051Testing软件测试网KqM1q*J7L!R

fo6W5|MV"J6g/l0 

t a h,}7h.|051Testing软件测试网'v*gjb2O%a L


"b3Y8Mu&|_gS0 

@{~%~$[6{@051Testing软件测试网3z:KvJG0w3b4q$E+cK

参考资料清单List of reference :51Testing软件测试网Y|)oPvC&m5u

d&g,D/Y(I6s ~0[1]    SAMS, 《精通shell编程》51Testing软件测试网qh-qQg4P }

#x-Gg)Q'Qc y0 

p zpNk%[[ h051Testing软件测试网'q w T)USB$f

 51Testing软件测试网3D,W"O-n-DO O3F$G


TAG:

 

评分:0

我来说两句

日历

« 2024-04-30  
 123456
78910111213
14151617181920
21222324252627
282930    

数据统计

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

RSS订阅

Open Toolbar