设为首页收藏本站|繁體中文 快速切换版块

 找回密码
 立即加入
搜索
查看: 1357|回复: 1

Gawk手册

[复制链接]
  • TA的每日心情
    奋斗
    2019-2-12 09:32
  • 签到天数: 1 天

    连续签到: 1 天

    [LV.1]初来乍到

    累计签到:1 天
    连续签到:1 天
    发表于 2008-6-12 16:31:32 | 显示全部楼层 |阅读模式

    马上加入,结交更多好友,共享更多资料,让你轻松玩转电力研学社区!

    您需要 登录 才可以下载或查看,没有账号?立即加入

    ×
    GAWK
    # I. s1 e; ^. L% V. Y7 {, v第一章 前言9 Y0 J2 f8 ?& j- [; @; M
    第二章 简介! G( ^! D+ E  }5 j" {
    第三章 读取输入档案
    1 c7 y8 y- R7 j# g- z: w! Y第四章 印出
    1 d  O, i. {7 b2 w5 l第五章 Patterns" U2 c7 v4 p' y
    第六章 算式(Expression)作为Actions的叙述" z: k+ z9 l! E/ ~
    第七章 Actions里面的控制叙述1 x6 R% g% s. n2 y" {
    第八章 内建函式(Built-in Functions)
    $ Q! Y, g; z, A$ x6 Z- o8 i! \第九章 使用者定义的函式
    ; J" Y4 s: }0 x' A& J* S4 Q第十章 □例
    ; k; F* h8 ^% \$ r2 ?第十一章 结论/ ^' X$ m1 r. K/ f- a

    ( a! q8 r7 V" e7 E$ w: l=======================================# C) Q5 N7 o' [2 w- t( J! E8 j
    第一章 前言# @3 \. @7 T; \% B& ]* H% q
    awk 是一个程式语言,对於资料的处理具有很强的功能。对於文3 H2 @. Z+ R' t/ y. Q
    字档里的资料做修改、比对、抽取等的处理,awk 能够以很短的程式" s5 f0 o3 m' k- v2 {3 a
    轻易地完成。如果使用 C 或 Pascal 等语言写程式完成上述的动作,: F: V. E* F3 R* r4 h, C. s; a
    会不方便且很花费时间,所写的程式也会很大。
    , ~* v, F! o. p. X3 p8 Zawk 能够依照使用者的定义格式来分解输入资料,也可依照使用
    / Z& o4 k+ M$ t) L" f7 }- G) B7 u者定义的格式来印出资料。. d9 D9 ^% C: |0 R5 M6 h
    awk 名称的由来是由它的原始设计者的姓氏之第一个字母而命名
    ' D( g' F/ l! d; ^3 m; I* D# Z2 u; ]:Alfred V. Aho, Peter J. Weinberger, Brian W. Kernighan。
    0 E/ Z+ C" ]; O$ P# @awk最初在1977年完成。一个新版本的awk在1985年被发表,它的功能
    3 A2 u4 O! U0 E) N9 }2 D- V( `: S比旧版本增强不少。
    $ |* D- j, K' O9 H/ W% P2 Ugawk 是GNU所做的 awk,gawk 最初在1986年完成,之後不断地
    2 T( n' x* y2 A2 s/ P# c被改进、更新。gawk 包含 awk 的所有功能。
    + S6 K. X$ C) m$ w' n9 r往後的 gawk 将以下面的2个输入档案来做例子说明。: X8 F: K: Z- K# x1 K
    档案'BBS-list':* X" G4 C2 ~- W( q
    aardvark 555-5553 1200/300 B
    ! T5 q' Q% v  `) G  {alpo-net 555-3412 2400/1200/300 A7 k8 `, @( y' {4 A- m/ {% H  z
    barfly 555-7685 1200/300 A
    : B7 y3 l( C' h, |- P3 ~7 Dbites 555-1675 2400/1200/300 A
    ! {& p6 i1 j  t& Xcamelot 555-0542 300 C* `5 ?% E  a! L9 S7 D
    core 555-2912 1200/300 C
    0 |3 Q- K+ f/ C) Tfooey 555-1234 2400/1200/300 B1 N# T2 k7 s- o( f4 X. n
    foot 555-6699 1200/300 B& I0 B" e5 M( C. M* j& R
    macfoo 555-6480 1200/300 A' d4 @/ r" t, N* T6 f2 ]+ {' p
    sdace 555-3430 2400/1200/300 A
    . X" L% Z; X* L2 `# ~0 z, a: Msabafoo 555-2127 1200/300 C
    : m# B/ ]+ R1 T5 w, Z. {; U档案'shipped':  G+ z% ?& U7 r2 [" M6 E
    Jan 13 25 15 115
    - a/ K# P9 C0 p, C3 r% R4 U! y' AFeb 15 32 24 226. `5 V1 e4 [& z  S. B
    Mar 15 24 34 228
    ' U2 w7 A1 e4 D' o8 h) QApr 31 52 63 420/ i# f3 C! l8 u3 t
    May 16 34 29 208
    ( [5 R# X* a% B$ |7 f  P( f1 bJun 31 42 75 492
    0 V% h4 M- I: vJul 24 34 67 4368 K; V* \, L" a# j% h+ n1 s
    Aug 15 34 47 316
    1 [1 }  O* y* HSep 13 55 37 2775 P1 Y9 q1 t$ T* U8 o
    Oct 29 54 68 525
    % z. n# g5 K  c+ y4 y* t# ^Nov 20 87 82 5777 G# |' ?& c; W# x
    Dec 17 35 61 4012 O! ]* e9 n: X/ `
    Jan 21 36 64 620
    7 C+ h1 d+ o6 OFeb 26 58 80 652
    5 n  I8 \: t  N9 R: tMar 24 75 70 495/ a/ J7 |0 y/ M
    Apr 21 70 74 514# a$ C. P# F/ z0 ^! s' i. Z; n. Q6 {

    6 m8 ~- ~& t1 y& q1 d第二章 简介
    6 @1 H' S: z3 }% T0 igawk 的主要功能是针对档案的每一行(line)搜寻指定的 patterns
    6 {$ k7 ]7 g7 A( v: w- R7 e3 c; F。当一行里有符合指定的 patterns,gawk 就会在此一行执行被指定3 c: G5 u: T+ \
    的 actions。 gawk 依此方式处理输入档案的每一行直到输入档案结
    . x4 e4 O3 O7 K8 N  W, }5 Q束。
    ; b: M  l' [3 @2 e8 Tgawk 程式是由很多的 pattern 与 action 所组成,action 写在
    ( G" Q! j; d0 K" [大括号 { } 里面,一个pattern後面就跟著一个action。整个 gawk 程
    $ b8 J+ U8 L/ ]式会像下面的样子:
    + a3 t- h. c) r, K$ `4 X% z4 E  [, Bpattern {action}4 m1 A% t1 ~0 v  s: n' m" r
    pattern {action}, I/ A0 ^1 R6 m
    在 gawk 程式里面的规则,pattern 或 action 能够被省略,但: n) g! o% [3 D$ I
    是两个不能同时被省略。如果 pattern 被省略,对於输入档里面的
    8 M! x9 }/ o. U9 {7 s每一行,action 都会被执行。如果 action 被省略,内定的 action
    " M9 Z! w' H2 c8 P7 |% A则会印出所有符合 pattern 的输入行。4 w3 p% k3 M( N* k& c- ~4 W
    . F+ `4 N# c- }1 _
    2.1 如何执行gawk程式
    5 O* Q, F0 o8 b8 Z- J* g3 p基本上,有2个方法可以执行gawk程式。) _& ~- B* v8 ?7 P4 ^: _
    □如果 gawk 程式很短,则 gawk 可以直接写在 command line,如下所示:4 D1 x. d2 F+ }, J% j- b' F
    gawk 'program' input-file1 input-file2 ...& H" R$ Y3 A  j, f- B& D
    其中 program 包括一些 pattern 和 action。' o5 A4 G* K1 z$ ]" Z
    □如果 gawk 程式较长,较为方便的做法是将 gawk 程式存在一个档案,2 C9 d! [3 ~! L- m
    即 patterns 与 actions 写在档名为 program-file 的档案里面,执行9 w( J7 r: V( P- y" l# R) Y
    gawk 的格式如下所示:  l& M/ ~3 S/ C
    gawk -f program-file input-file1 input-file2 ...- c. R( A3 d- n- @
    gawk 程式的档案不止一个时,执行gawk 的格式如下所示:
    + t" U' B2 ?8 fgawk -f program-file1 -f program-file2 ... input-file1% i, a# d. }) o0 Q
    input-file2 ...
    $ I- W5 \# k) J; ~, d: e! W- s* |4 u8 q) P! J" T) S: y# c' F9 X
    2.2 一个简单的例子+ k' m/ i+ f9 c1 r# x8 x
    现在我们举一个简单的例子,因为 gawk 程式很短,所以将 gawk 程
    2 y$ G& w* P" z% o式直接写在 command line。
    # l0 p5 f$ Q$ ^& m8 s  Tgawk '/foo/ {print $0}' BBS-list5 Z! z5 l3 U- n: @
    实际的 gawk 程式为 /foo/ {print $0}。/foo/ 为 pattern,意思为搜
    , @9 Z/ |; X9 G0 f) R! f( v5 k( K寻输入档里的每一行是否含有子字串 'foo',如果含有 'foo' 则执行 action。
    ; o8 {/ {1 f/ v0 |8 ]  Q6 Raction 为 print $0,是将现在这一行的内容印出。BBS-list 是输入的档案。
    : y( L+ J* F+ g# J执行完上述指令後,会印出下面的结果:
    * G/ H: F* G$ s% E. {9 _2 M5 Qfooey 555-1234 2400/1200/300 B
    ; Q. `4 i6 |1 P* k/ Xfoot 555-6699 1200/300 B$ r0 @* T. C8 |$ v
    macfoo 555-6480 1200/300 A  C& [) [  F9 w/ i$ l
    sabafoo 555-2127 1200/300 C
    7 W+ X1 h# O8 {1 @  ^5 |
    6 y5 g  U* N6 b: s% m' e2.3 一个较复杂的例子+ i" N0 U9 m* \# A" ]) s
    gawk '$1 == "Feb" {sum=$2+$3} END {print sum}' shipped
    & j- b* k2 w% \" S; x" P: r' X5 _现在这个例子会将输入档 'shipped' 的第一个栏位与 "Feb" 做比较
      J( v8 F2 ]$ N- W2 z: P% l,如果相等,则其对应的第2栏位与第3栏位的值会被加到变数 sum。
    $ C! x$ v+ t7 a1 [6 U' K- U对於输入档的每一行重复上述的动作,直到输入档的每一行都被处理& ?2 w+ L1 d$ u+ L% R2 C0 J, D
    过为止。最後将 sum 的值印出。END {print sum} 的意思为在所有的输. Y4 o4 F4 P5 F  q/ k) M1 I
    入读完之後,执行一次 print sum 的动作,也就是把 sum 的值印出。# h% e6 y& w6 K, d& Y
    下面是执行的结果:
    2 p9 {5 r# b% ^; S* ~84; u0 a  k5 r" X  ?2 b+ M  @
    7 B! W: y, I. y5 H$ s2 }
    第三章 读取输入档案
    * i) p, ~( C; ]5 {# ]5 ogawk的输入可以从标准输入或指定的档案里读取。输入的读取单4 T# n# Y: i2 x2 L+ ]# a
    位被称为”记录”(records),gawk 在做处理时,是一个记录一个记
    ) V/ r6 H8 K% z" k: ^  c; e录地处理。每个记录的内定值是一行(line),一个记录又被分为多个
    & l( ^' X$ Q* Q1 ~. u栏位(fields)。8 v' q& Y7 K7 {2 ?
      d' E  U" |3 A( I& }  _9 N
    3.1 如何将输入分解成记录(records)
    , ?0 n/ ?/ s# Xgawk 语言会把输入分解成记录(record)。记录与记录之间是以
    ' S. X" Y3 n: I! B/ Vrecord separator 隔开,record separator 的内定值是表示新一行的3 S  I; w  t0 l4 A  g, `
    字元(newline character),因此内定的 record separator 使得文字4 m7 g/ V: i' R
    的每一行是一个记录。
    6 T, `/ m: }2 P4 j7 Trecord separator 随著内建变数 RS 的改变而改变。RS 是一个字串,, m$ i' C) t3 `
    它的内定值是"\n"。仅有 RS 的第一个字元是有效的,它被当作 record
    9 G$ e1 r4 t; k* U: k1 Vseparator,而 RS 的其它字元会被忽略。
    2 Z7 N6 j; B/ {) @, ?内建变数 FNR 会储存目前的输入档案已经被读取的记录之个数。内4 Z% u# _  Q% l' z8 Y
    建变数 NR 会储存目前为止所有的输入档案已经被读取的记录之个数。: Y- l; H( [6 _' p5 I9 g" X

    7 G$ m. \1 @1 h# R+ M6 t' G3.2 栏位(field). N/ y: S! v- \/ o9 T+ C" F6 A
    gawk 会自动将每个记录分解成多个栏位 (field)。类似於字在一
    * ?$ c( C1 W; a& A7 a* {  I行里面,gawk 的内定动作会认为栏位之间是以 whitespace 分开。在7 G* N' t0 Y" n
    gawk 里,whitespace 的意思是一个或多个空白或 tabs。9 z6 R: @1 f( l1 W5 q
    在 gawk 程式里面,以'$1'表示第一个栏位,'$2'表示第二个栏位! K% g3 Y& l6 n& _5 e3 `" x
    ,依此类推。举个例子,假设输入的一行如下所示:; j3 ~4 @7 `, i# b7 q: q/ M
    This seems like a pretty nice example.
    1 h( e2 O) |, c0 @; q/ n第一个栏位或 $1 是'This',第二个栏位或 $2 是 'seems',依此类推。" ^; P# u9 Y. |8 z+ `" p
    有个地方值得特别注意,第七个栏位或 $7 是'example.'而非'example'。  `3 u& f, z, R7 s5 U
    不论有多少栏位,$NF 可用来表示一个记录的最後一个栏位。以& M% ~5 S8 p3 h. `. A* g1 p
    上面的例子为例,$NF 与 $7 相同,也就是'example.'。
      i+ O* S  ~: e, u6 h2 INF 是一个内建变数,它的值表示目前这个记录之栏位的个数。
    0 m6 ]2 g7 x% F$0,看起来好像是第零个栏位,它是一个特例,它表示整个记录。
    : \( Z7 G* l1 k; t- z$ x8 ~% V3 h下面是一个较复杂的例子:1 A) E$ ~# F. k/ F
    gawk '$1~/foo/ {print $0}' BBS-list3 |8 S  \9 E4 g2 [! @
    结果如下:) u% g8 s" \$ _$ ~) _, i2 |! [7 y
    fooey 555-1234 2400/1200/300 B5 a; R3 p8 h. t+ `' d* Y: ]& L
    foot 555-6699 1200/300 B% _! G' M) h, `# Y9 V) F( f6 F
    macfoo 555-6480 1200/300 A
    2 e% Y( P: O+ J8 f3 X9 n. K4 psabafoo 555-2127 1200/300 C
    5 J- n! J% u+ b' D: B/ y- {这个例子是把输入档'BBS-list'的每个记录的第一个栏位作检查,如. \1 K9 k: n( V8 a
    果它含有子字串'foo',则这一个记录会被印出。
    % T4 D/ C# p. R  N& K. M) e+ x+ {4 Z, ~! `8 R& S
    3.3 如何将记录分解成栏位9 s8 t' C' Z; c3 ~
    gawk 根据 field separator 将一个记录分解成栏位。field sepa-
    7 ~7 W1 E& n* t7 O1 Orator 以内建变数 FS 表示。
    5 V  O' D- y# d# r8 v8 E& _& \举个例子,假如 field separator 是'oo',则下面的行:
    ( J% B1 [$ e2 s! j7 bmoo goo gai pan
    # q6 e# `6 W8 k% N会被分成三个栏位:'m'、' g'、' gai pan'。* ]: h7 L  V  N4 [# I1 v" S
    在 gawk 程式里,可以使用'='来改变 FS 的值。例如:
    0 A& Z: n4 D3 h' V7 Bgawk 'BEGIN {FS=","}; {print $2}'4 S: k; S; {) ~% }
    输入行如下:
    ! ^# L3 h' s/ Y2 P) wJohn Q. Smith, 29 Oak St., Walamazoo, MI 42139
    9 G2 ~1 k3 N6 v4 p. o7 I执行gawk的结果将印出字串 ' 29 Oak St.'。BEGIN 後面的 action 会在
    $ j4 Q/ U+ S4 m' b" k第一个记录被读取之前执行一次。
      p! |( V/ ]  x0 a
      B' {" W  Z4 Y第四章 印出! A, O" a) Z, x
    在gawk程式里,actions 最常做的事就是印出(printing)。简单, z# }0 u3 L" J' A
    的印出,使用 printe叙述。复杂格式的印出,使用 printf 叙述。+ f/ v5 P( o! R
    : N; j- B* V7 l" ^0 V2 @0 Y2 X
    4.1 print叙述) Q, Y: }# j9 ?: w8 O
    print 叙述用在简单、标准的输出格式。叙述的格式如下所示:
    & ?5 x! X+ f, {print item1, item2, ...1 p: U: l1 l5 Q1 P. F
    输出时,各个 item 之间会以一个空白分开,最後会换行(newline)。
    " r9 B! L) p. s( Y* _2 b如果 'print'叙述之後没有跟著任何东西,它与'print $0'的效
    , W3 n+ Z6 L; v5 A/ N% q1 f, q果一样,它会印出现在的记录(record)。要印出空白行可使用'print
    4 k. C- i: B" o# y" z% u""'。 印出一段固定的文字,可用双引号将文字的两边括起来,例如# [& {7 }2 H. e: J& q
    'print "Hello there"'。( R9 d% `+ N' M1 k
    这里是一个例子,它会把每个输入记录的前二个栏位印出:
    8 C, W1 J! U! o( ogawk '{print $1,$2}' shipped
    0 h$ K$ @0 N3 r1 y结果如下所示:- f! P& a: a' C! c6 c. Q7 G% P
    Jan 13$ W% A4 u; L: j7 C; v/ X
    Feb 15
    5 ?0 C- `5 i/ |- QMar 15
    4 G' ?9 p% O9 w: G( SApr 31
    # p% O0 f" G; P& V. m8 GMay 16- O4 D, a$ G" r7 T2 Y: m8 ?4 S0 q
    Jun 31
    $ s! I% {5 M+ W1 _' g% Z8 |Jul 24
    - X' w0 I" [% @' bAug 15
    7 x: h1 l7 b% D, \6 t- E; ?% ^Sep 13
      j4 o' ^  d+ q- ]  R+ v% q" e5 mOct 290 G4 X$ C9 l9 z
    Nov 20: [) U& A: N/ |' a! t
    Dec 179 o+ L/ K" E  U% F
    Jan 21
    1 v6 L& p7 S! YFeb 26: b. X7 Z6 M# n, N, |
    Mar 24
    " o$ B% b5 ?9 A9 B- y" AApr 21, s6 S( W) \$ _7 N; i& q2 h

    $ p% |3 x' a, \, W' S% a4.2 Output Separators( s9 F" V& t. x/ G, y  u% O
    前面我们已提过如果 print 叙述包含有多个 item,item 之间
    0 V9 v4 |' P7 Q+ a7 W用逗点分开,则印出时各个item会被一个空白隔开。你能够使用任何( p% K: P0 K# J. P; I' x# q
    的字串作为 output field separator,可以经由内建变数 OFS 的设: }1 d) C& `  ^% Z; D7 Y
    定来更改 output field separator。OFS 的初始值为" ",即一格的
    ) h% w1 U& q' l2 e空白。
    5 C. e& N& |7 u( Z) X$ P9 U1 V' r/ R整个 print 叙述的输出被称为 output record。print 叙述输
    ' u9 X" o! b- q/ G( V- }2 w& q出 output record 之後,会接著输出一个字串,此字串称为 output! e. P% k( d9 y6 r
    record separator。内建变数 ORS 用来指明此字串。ORS 的初始值
    0 h, X' I* |1 `为 "\n",也就是换行。; e0 R( N. f. W1 @% e( ~! u, Y
    下面这个例子会印出每个记录的第一个栏位和第二个栏位,此二
    + q5 F6 i2 h7 Z个栏位之间以分号';'分开,每行输出之後会加入一个空白行。. d3 R# @* C4 `* }7 X4 y6 S
    gawk 'BEGIN {OFS=";"; ORS="\n\n"} {print $1, $2}' BBS-list
    , B/ h* s$ X" G4 q. ]& _结果如下所示:9 U/ Z- d8 U5 e- A8 r+ T# e5 z
    aardvark;555-55539 d0 D: G3 c: Y$ k$ ~8 X9 [
    alpo-net;555-3412
    / d6 c; [3 t* z  `" Kbarfly;555-7685
    $ z+ R0 I; S5 T0 y" xbites;555-1675
    " U- u9 }+ N4 n" g, Ccamelot;555-05426 j" I% f, c5 a5 V+ E- ^( b2 j
    core;555-2912
    - ]  l6 C7 o0 e, |fooey;555-1234
    - }; z1 G$ e  @3 K3 l! z8 wfoot;555-6699
      v, y  l* {& s, q0 V3 Imacfoo;555-6480
    3 ?. I" ^) f# T8 I. psdace;555-3430
    , Y* A  ~# g1 K6 }sabafoo;555-2127# g8 S  _' S9 `0 G+ t6 o

    7 J! n2 B5 w6 Z1 o  e* A4.3 printf叙述
    2 l& x6 T3 |. u# J" M2 hprintf 叙述会使得输出格式较容易精确地控制。printf 叙述可以3 [  U4 ~) L0 ~3 k  p
    指定每个 item 印出的宽度,也可以指定数字的各种型式。, S3 J1 \5 }2 W0 K8 Q4 E2 g4 b) n, X, D
    printf 叙述的格式如下:
    : U. i" n- t7 T/ P, v0 hprintf format, item1, item2, ...6 m4 m& z" T& n3 l8 z) m. X- T
    print 与 printf 的差别是在於 format, printf 的引数比 print
      Y) [' ?3 @% A  u/ v( j4 g- |多了字串 format。format 的型式与 ANSI C 的 printf 之格式相同。* F; k! j8 ]( D+ g  {! p% F0 Q" Y
    printf 并不会做自动换行的动作。内建变数 OFS 与 ORS 对 printf 叙" l. g6 ^: j3 Q! {+ V' w
    述没有任何影响。5 u- n! h# A8 _" |* `
    格式的指定以字元'%'开始,後面接著格式控制字母。
    : ]8 s& I; d3 ?' H格式控制字母如下所示:- u) y0 a0 J/ z7 e
    'c' 将数字以 ASCII 字元印出。
    % n+ ]* W1 O' p7 C: R% N# W例如'printf "%C",65'会印出字元'A'。
    4 H* N9 K; r/ n+ F% c$ D'd' 印出十进位的整数。7 J* U: E3 ~3 z' e5 T: v% S
    'i' 印出十进位的整数。
    4 B+ x) p9 u* E/ Y, h'e' 将数字以科学符号的形式印出。
    & N6 e% e: c# G( A& d0 P" p+ x例如' O' j1 ?( l3 a# o+ G
    print "$4.3e",1950, j! L$ ]) f6 U6 j9 O, L  o
    结果会印出'1.950e+03'。
    : v2 V7 ], |" ~'f' 将数字以浮点的形式印出。
    $ c; n/ I2 h3 }1 p& |2 m( u'g' 将数字以科学符号的形式或浮点的形式印出。数字的绝对值如果2 ?( G% x9 G) r: S0 X6 _! F& ^+ s
    大於等於0.0001则以浮点的形式印出,否则以科学符号的形式印0 G) w5 ^1 {* Y2 n  ^6 X7 ]8 R1 H' g
    出。
    2 T- {( h" ]6 L'o' 印出无号的八进位整数。5 T+ K' a# \+ a6 f" v
    's' 印出一个字串。
    6 K8 v9 @/ s- v+ t'x' 印出无号的十六进位整数。10至15以'a'至'f'表示。' Q" ^! X2 {9 H" z' F5 B
    'X' 印出无号的十六进位整数。10至15以'A'至'F"表示。4 X5 P" R, }0 ?3 ?& ?* i8 K6 T& [
    '%' 它并不是真正的格式控制字母,'%%"将印出"%'。; m2 _; X  x. A* T4 |: H  E
    在 % 与格式控制字母之间可加入 modifier,modifier 是用来进一6 _* M4 H  ]( t4 e
    步控制输出的格式。可能的 modifier 如下所示:7 i# I- W/ Y: M8 v, l
    '-' 使用在 width 之前,指明是向左靠齐。如果'-'没有出现,则会在
    0 `( L3 I5 ?6 h) _+ C被指定的宽度向右靠齐。例如:: {% d! N# |- q" _1 }, C" S
    printf "%-4S", "foo"
    ' ^; }# P+ {; b2 f( S0 _6 d会印出'foo '。9 K2 |8 ^3 L# U3 E
    'width' 这一个数字指示相对应的栏位印出时的宽度。例如:5 H. ~: w$ N" u
    printf "%4s","foo"1 S+ q9 R7 {& `! w, m
    会印出' foo'。
    ' F$ D/ I9 T) Z1 w8 E8 ]width 的值是一个最小宽度而非最大宽度。如果一个 item 的0 q0 }5 F5 i6 s2 s/ G* W* O
    值需要的宽度比 width 大,则不受 width 的影响。例如
    ( {6 H: S- b# U4 |printf "%4s","foobar"
    + Q7 ^7 R- }( @; b; h3 ~7 Y6 }将印出'foobar'。
      u- X! |' O( r* P'.prec' 此数字指定印出时的精确度。它指定小数点右边的位数。如
    ! J' V0 @3 R6 A- l果是要印出一个字串,它指定此字串最多会被印出多少个字
    ( p% A, P# x+ y0 E6 m( \1 W5 s$ L元。
    4 _7 s- S% ]4 S% d
    & w3 R7 b  p" ]9 s: y: i) z第五章 patterns1 Z  w0 W3 M( z2 k& q; V. d4 T
    在 gawk 程式里面,当 pattern 符合现在的输入记录(record),其+ O4 m: G- o' }1 R& O, m2 E
    相对应的 action 才会被执行。3 y: j6 K; G: a9 p, {1 {

    * ?) S# z" L5 S0 y, {& V5 H5.1 Pattern的种类! W& ?1 N: a6 s. y2 v
    这里对 gawk 的各种 pattern 型式作一整理:2 B6 g: ^# [6 W9 L: [
    /regular expression/% c' C0 I2 I. u# W
    一个 regular expression 当作一个 pattern。每当输入记录 (3 U1 ]" m, X+ @; X7 w( B
    record)含有 regular expression 就视为符合。6 n  @2 ~, ]( T
    expression8 N. I( s7 s4 X. X' b
    一个单一的 expression。当一个值不为 0 或一个字串不是空的,
    & N- ~5 e! o# D# C1 |则可视为符合。
    : @$ ?: K. t; H& s/ |pat1,pat2
    $ ?0 T+ d( ?- t: f0 p一对的 patterns 以逗号分开,指定记录的□围。
    - n/ y- G- t  k5 Z3 A+ C" ]BEGIN
    ! v' {% D8 O; B1 O# JEND
    7 `; P: Q; {/ t这是特别的 pattern, gawk 在开始执行或要结束时会分别执行相
    ( S1 N) v- K7 s7 e7 b1 g对应於BEGIN或END的 action。
    0 q8 l2 K. [! ~& }null' B; m  i7 |6 K/ C( s7 u" \5 Z
    这是一个空的pattern,对於每个输入记录皆视为符合pattern。! f" A/ P" N6 T% Y3 ^3 S" X
    : b" M/ U9 H& M3 i
    5.2 Regular Expressions当作Patterns
    / Z) k9 ?( A( ~8 f, \& s/ W一个 regular expression 可简写为 regexp,是一种描述字串的方
    / R  J8 V) y5 T: A) ]法。一个 regular expression 以斜线('/')包围当作 gawk 的 pattern。7 E0 K) L6 r9 s5 @( P5 Z
    如果输入记录含有 regexp 就视为符合。例如:pattern 为 /foo/,
    $ R2 i, t* h- |, G对於任何输入记录含有'foo'则视为符合。+ j7 V% l/ ?1 Z" `! ~' S$ h/ z+ t
    下面的例子会将含有'foo'的输入记录之第2个栏位印出。* T3 M5 \0 u: ]
    gawk '/foo/ {print $2}' BBS-list
    / [! d* j" R0 h4 c/ `3 @/ w结果如下:
      v. u! R1 h- u3 V5 \. I& H# I# @555-1234/ y7 Z" p( l1 g7 k) Y! v
    555-6699* o! P5 {" t4 I
    555-6480
    8 h! R! v, R/ P8 [555-2127
    5 N! B: O1 K, M7 \: o) Oregexp 也能使用在比较的算式。
    ) ^; }, p" u, M+ ?) [exp ~ /regexp/
    3 p/ D6 W& K5 {8 L如果 exp 符合 regexp,则结果为真(true)。. ?9 t$ \& [3 I% u/ r: A' g
    exp !~ /regexp/* B1 A' F- `. l8 ]
    如果 exp 不符合 regexp,则结果为真。/ }; [) I# w7 B! k- ~5 Z$ E0 N
    ! ?3 q5 j- v! ~) |4 J
    5.3 比较的算式当作Patterns
    ' P2 s# Z/ p: c6 h2 f6 s. I; A比较的 pattern 用来测试两个数字或字串的关系诸如大於、等於
    9 R+ L7 {2 ^7 y、小於。下面列出一些比较的pattern:+ X4 m! e- l# S
    x<y 如果 x 小於 y,则结果为真。6 g: Y' Z: D" w0 z3 ^
    x<=y 如果 x 小於、等於 y,则结果为真。
    9 y  n# R, v. t9 R+ ]( p+ b- o, xx>y 如果 x 大於 y,则结果为真。/ F% ]; Z9 r' |9 }: ?* H( d
    x>=y 如果 x 大於、等於 y,则结果为真。) M$ k6 i8 C/ B) r* O: W0 ?
    x==y 如果 x 等於 y,则结果为真。
    3 @1 ~" }  V$ Z' i" Mx!=y 如果 x 不等於 y,则结果为真。+ i. `3 I5 h# g+ r: z
    x~y 如果 x 符合 regular expression y,则结果为真。
    ( E; f; ~2 O7 e6 {4 mx!~y 如果 x 不符合 regular expression y,则结果为真。- x1 r. X+ @' w* n) ^% z$ g' `
    上面所提到的 x 与 y,如果二者皆是数字则视为数字之间的比较,
    6 ~+ s$ `" D; D" {. T否则它们会被转换成字串且以字串的形式做比较。两个字串的比较,
    ( R& z$ b$ a, ?( w  I会先比较第一个字元,然後比较第二个字元,依此类推,直到有不同
    * o2 {  |8 t% B( b! U的地方出现为止。如果两个字串在较短的一个结束之前是相等,则视' f8 Y+ T7 b9 b, \7 `- j
    为长的字串比短的字串大。例如 "10" 比 "9" 小,"abc" 比 "abcd" 小。: I6 O  ]- \9 B' t# H

    6 \( s# }7 p  P" }5.4 使用布林运算的Patterns3 c; a) `0 x9 x8 ^% i# [" w
    一个布林(boolean) pattern 是使用布林运算"或"('||'),"及"
    , R& Q/ e* c, {9 \5 e/ B('&&'),"反"('!')来组合其它的pattern。' f+ }% A+ d- r. S3 K
    例如:
    - k" X$ B4 X9 zgawk '/2400/ && /foo/' BBS-list) }4 F( ~( f! C  C- R" H' @
    gawk '/2400/ || /foo/' BBS-list# p- f3 T) I. Q: X& S
    gawk '! /foo/' BBS-list( b7 A$ ^+ o5 ]# \; z+ ^5 P' {

    - [, k  o# I4 G6 |7 [第六章 算式(Expression)作为Actions的叙述: C3 a1 ~( I6 c6 P
    算式(Expression) 是gawk程式里面action的基本构成者。0 n& I! H/ d4 V* y
    ! K0 |  Y# i1 P4 ^
    6.1 算术运算
    2 }2 k: w" L  L2 C) t. agawk 里的算术运算如下所示:
    & \2 ~+ E  C  ?9 Mx+y 加" {  q: H* b9 S7 V0 T2 u9 D' ~4 b
    x-y 减$ R" G1 }4 l9 {( _$ p' U
    -x 负/ ^# B, {1 _4 i3 H* l
    +x 正。实际上没有任何影响。0 j* Y, G7 |% M4 s
    x*y 乘* D6 O$ |( H& V. i8 h& c/ m" R, j
    x/y 除
    / \4 e9 B* l( k/ [: b: a# \, wx%y 求馀数。例如 5%3=2。2 j, U# ~, X6 u3 q
    x^y
    2 N: W  H; E" J3 ^x**y x 的 y 次方。例如2^3=8。
    % B6 u& Y- X. }* j* N6 ?" u( s$ I3 I! ?6 s, K
    6.2 比较算式与布林算式
    2 R; ^6 s& p# b6 {比较算式 (comparison expression) 用来比较字串或数字的关系
    : D; o7 \* Z- V* Y! b,运算符号与 C 语言相同。表列如下:/ w, [! C; ~; ]# |6 N. a: ]
    x<y
    ; P# g3 _4 v4 F- a$ px<=y! G2 _) d7 z, \/ c
    x>y' g7 g, Q7 ?- _' l
    x>=y, C) V/ V  _: V  t* w
    x==y
    : [) s, R& l* h" R/ Ux!=y
    6 h0 \. I; |9 \. G. M% @$ ex~y7 |0 u; i( b7 M/ N
    x!~y
    * w' ]1 y# N6 G7 v, X比较的结果为真(true)则其值是 1。否则其值是 0。
    . u, P! A7 D" F( n布林算式(boolean expression)有下面三种:
    1 U5 y1 ~9 _, L0 \, q% bboolean1 && boolean28 M9 ?( y2 Y$ D( q6 l
    boolean1 || boolean2
    " `7 z: |9 g' i0 W/ c  S, {  [5 E8 P! boolean
    ) C0 H5 v( l  o  F! L
    7 [3 V7 C" d1 Q7 e1 K% P6.3 条件算式(Conditional Expressions)7 ?; t1 p" S/ h$ h+ b; M" s( p  Y
    一个条件式算式是一种特别的算式,它含有3个运算元。
    2 L& |' [$ w1 S% a* X! }- X& [条件式算式与C语言的相同:/ u  o* Y$ L% ~  n5 u
    selector ? if-true-exp : if-false-exp
    ! k- d" b) {& }- C$ N+ R它有3个子算式。第一个子算式selector 首先会被计算。如果是真,
    & |' r1 ?; k# S# E. u/ V, O则if-true-exp会被计算且它的值变成整个算式的值。否则if-false-
    $ ]+ P9 `4 J& Lexp 会被计算且它的值变成整个算式的值。
    7 T9 ~7 h, q& g例如下面的例子会产生x的绝对值:
    $ ]# D$ {& _2 ^5 C& J* ax>0 ? x : -x
    . e( E$ z1 }/ ~
    1 R: O" A# e* P. ^+ d! \第七章 Actions里面的控制叙述
    & k+ \: q3 J$ o$ W8 Q# T在 gawk 程式里面,控制叙述诸如 if、while 等控制程式执行的流9 ?$ o* R7 |, t# N% j
    程。在 gawk 里的控制叙述与 C 的类似。: b# \% U" f2 A% M2 G0 {: s
    很多的控制叙述会包括其它的叙述,被包括的叙述称为 body。假
    0 Q1 `; A& v3 t) j/ D. s6 U如 body 里面包括一个以上的叙述,必须以大括弧 { } 将这些叙述括起- z2 S& ^+ Y2 r) x" g$ e# {: G
    来,而各个叙述之间需以换行(newline)或分号隔开。5 q9 v" J" [7 i- G' ]9 c+ ~$ p

    2 y& q4 |% J) k4 Y/ i7.1 if 叙述
    9 b+ G6 k7 L1 Gif (condition) then-body [else else-body]
    3 K$ n( n! k/ j3 J2 M: W; k, H如果 condition 为真(true),则执行 then-body,否则执行 else-body。/ B* O& a5 X0 [- C
    举一个例子如下:: i! F5 R$ l1 E  T7 K- E, T
    if (x % 2 == 0)# ^) e' C  Q) _& }
    print "x is even"0 s3 f4 u7 b+ y! G9 h
    else
    6 Q: t1 {0 y, _print "x is odd"$ Q$ ^+ P/ D( Z$ X
    9 N! i1 ^& S" \0 l' h( D2 W
    7.2 while 叙述1 `+ w0 s0 g( p5 ?1 k+ o
    while (condition)' p& |* l2 P2 N2 _+ [! a" Z: i
    body. g" ~# j& v9 {' c, w
    while 叙述做的第一件事就是测试 condition。假如 condition 为真则! z7 c3 ^6 T* i! H# i
    执行 body 的叙述。body 的叙述执行完後,会再测试 condition,假如
    ; H' |" V: H, B- |condition 为真,则 body 会再度被执行。这个过程会一直被重复直到0 g7 S2 t" p/ n/ ^+ d
    condition 不再是真。如果 condition 第一次测试就是伪(false),则
    * A+ `5 I# ]6 E$ e: V6 V* \$ x6 abody 从没有被执行。
    ; S) A3 ~3 ?7 r; f4 ~9 O) Z# i5 m下面的例子会印出每个输入记录(record)的前三个栏位。
    , B) x& T) Y" d: b& x- K% d) Y9 F0 Agawk '{ i=1( u2 x; i# M2 V2 E
    while (i <= 3) {% I2 N0 R6 u" B' ^. t; Z9 w
    print $i
    6 j# e. e+ a, ]& c3 ?i++6 K' Z# w! v' x- y
    }3 Q- `3 L% f' `% `" P
    }'7 p/ @. @- V) w) z

    ) D5 ?5 B% b/ q8 F; ?7.3 do-while 叙述7 o% F  [& r) ~9 n9 ^, L
    do
    . `9 z6 _; W/ e; d+ S' Zbody3 U) F" N% u& f! B* E7 J  F
    while (condition)) K4 M% s! Z. G+ p3 h! P; o
    这个 do loop 执行 body 一次,然後只要 condition 是真则会重复执行 body。; _" H1 A0 t+ G9 O9 t
    即使开始时 condition 是伪,body 也会被执行一次。
    " j* h7 s$ V1 ~下面的例子会印出每个输入记录十次。
    # W5 J0 H- D) }gawk '{ i= 13 L6 j* q: A- K0 L1 Y3 l
    do {, Y- ~1 g7 `& J9 P" `5 H, N0 _
    print $03 t! ?% f- a+ `* ~
    i++
    ( L6 _5 V5 U& W; x# I" E" C} while (i <= 10)
    5 j* {* d* G( g* ?$ ?: N; V}'
    2 s3 F3 l. u7 H+ G6 P8 C9 f8 @- t# N& ^1 m
    7.4 for 叙述
    7 ]3 X, Q: t% |- n+ r3 J0 a6 \" Q; c+ bfor (initialization; condition; increment)  ~% a; d+ Q/ X
    body, \6 ^+ }& i3 e" z2 X/ p3 ?
    此叙述开始时会执行initialization,然後只要 condition是真,它
    6 `5 |7 Q( F7 g# f; B( J会重复执行body与做increment 。
    . n% ^2 \5 T8 c' @下面的例子会印出每个输入记录的前三个栏位。+ x8 ^3 Y6 [: h/ R) \# x0 R0 ^
    gawk '{ for (i=1; i<=3; i++)# h5 S' b: J- m4 `) l" {2 s7 J
    print $i- s3 w2 w! q! e
    }'
    0 Z6 i2 S3 ?2 U' D# C$ ]' P  ]* K6 u
    7.5 break 叙述2 t9 c$ W. _8 p8 u
    break 叙述会跳出包含它的 for、while、do-while 回圈的最内层。
    . q. W1 _% w, o0 }* [$ I下面的例子会找出任何整数的最小除数,它也会判断是否为质数。
    / `% U: h7 l  W4 p* jgawk '# find smallest divisor of num* Q0 H" H/ w# e; @
    { num=$1
    6 X& _  @4 v) \: ^for (div=2; div*div <=num; div++)
    + p+ K" p3 K+ @& B0 e: kif (num % div == 0)
    3 e* Z/ d( y' t1 W. qbreak
    7 L! N0 p( P8 E) D# pif (num % div == 0)
    ! }; J# r9 w6 vprintf "Smallest divisor of %d is %d\n", num, div
    # j( ~" H: K2 P0 z! K) z; Qelse
    0 `; I6 I+ M! f/ |* Y: R* \printf "%d is prime\n", num }'8 D! W0 y7 m# ]! p

    , ^5 U: g$ L5 D4 U9 D7.6 continue 叙述5 d) F5 s; t" G6 N: w
    continue 叙述使用於 for、while、do-while 回圈内部,它会跳
    9 m, c9 H" [! F( O6 M" o: [过回圈 body 的剩馀部分,使得它立刻进行下一次回圈的执行。
    ) a$ I5 Y8 Q; A& s0 q$ F2 ~下面的例子会印出 0 至 20 的全部数字,但是 5 并不会被印出。9 Z5 w6 o# I7 V
    gawk 'BEGIN {
    3 V9 S6 J' Y' J% _6 Q/ lfor (x=0; x<=20; x++) {
    2 G+ F! x. U5 C' n2 z" P+ gif (x==5)4 @8 i0 ?5 k. z! |  x2 I& b
    continue& ?  `, b4 m( S  I. A" d) x
    printf ("%d",x)! h4 f( b! u, M8 n+ e* O2 y- b+ J
    }
    : B/ ^3 ?5 t( b8 e& E' I6 J* gprint ""
      W* a1 Q7 r% C& J8 W}'2 w. N) M5 D+ I- G; k4 L& t1 ^7 X

    4 X4 r+ ^2 j- B# }' P0 s7.7 next 叙述、next file 叙述、exit 叙述
    ; K: v+ Y  z- e0 a4 k2 Unext 叙述强迫 gawk 立刻停止处理目前的记录(record)而继续下一
    2 P, P8 v  U: y: U8 N+ \个记录。
    + S7 y+ }5 X9 O1 }; T' fnext file 叙述类似 next。然而,它强迫 gawk 立刻停止处理目前
    7 `. P6 `# }4 I$ A( J1 R的资料档。2 o5 ~5 r1 s+ x' {  `- }
    exit 叙述会使得 gawk 程式停止执行而跳出。然而,如果 END 出现$ M* h3 g) v! Q/ x
    ,它会去执行 END 的 actions。& y7 C: q& o0 c' s8 v0 v1 ?1 l( ?
    ( l3 [4 H1 N. h# ?+ p! Y
    第八章 内建函式(Built-in Functions)  |5 J. f: @& D% c! |
    内建函式是 gawk 内建的函式,可在 gawk 程式的任何地方呼叫内建3 X: u  H4 _- P& i$ F# s9 T, Q
    函式。
    : {- ?/ l$ e% j  r9 H2 V8 J
    & L6 n" P6 B" }# z% \( `8.1 数值方面的内建函式
      g3 b* Z, U: P* x. I- Jint(x) 求出 x 的整数部份,朝向 0 的方向做舍去。例如:int(3.9)) O: G1 S! C4 @' \# }( T9 E/ v
    是 3,int(-3.9) 是 -3。" ]3 e* Z, [6 i& a
    sqrt(x) 求出 x 正的平方根值。例 sqrt(4)=22 m, {  x0 ~; e( ?* R5 G. L2 p
    exp(x) 求出 x 的次方。例 exp(2) 即是求 e*e 。# Y* Z$ u3 v+ P0 I8 w
    log(x) 求出 x 的自然对数。5 f, T& n$ O8 Y# S8 {4 F
    sin(x) 求出 x 的 sine 值,x 是弪度量。6 p2 z" u) L. c
    cos(x) 求出 x 的 cosine 值,x 是弪度量。
    0 s' O$ H6 X6 d  |) g$ Tatan2(y,x) 求 y/x 的 arctangent 值,所求出的值其单位是弪度量。: A5 Y8 ?4 u6 W! Y2 g) B3 ~
    rand() 得出一个乱数值。此乱数值平均分布在 0 和 1 之间。这个5 y# q! k6 d6 \8 m4 `( a
    值不会是 0,也不会是 1。
    0 R0 k6 r+ G; J4 ~9 [$ b每次执行 gawk,rand 开始产生数字从相同点或 seed。
    1 s. G5 H& Y+ C7 F8 Msrand(x) 设定产生乱数的开始点或 seed 为 x。如果在第二次你设# }4 E7 @+ |% e
    定相同的 seed 值,你将再度得到相同序列的乱数值。
      c. o7 B& ~# i. k5 C如果省略引数 x,例如 srand(),则现在的日期、时间会% {3 s6 {# h" \4 o0 K# {
    被当成 seed。这个方法可使得乱数值是真正不可预测的。
    . C4 U2 _0 M: ^$ esrand 的传回值(return value)是前次所设定的 seed 值。
    " w5 w3 v) h) ~! b/ l6 x5 c- c2 A$ c6 v1 i$ b+ a1 A) C% f
    8.2 字串方面的内建函式# @5 C' W. q- ?" d8 l+ r( `! l
    index(in, find)
    1 D' f4 @* z' l" P2 w它会在字串 in 里面,寻找字串 find 第一次出现的地方,传回值是
    " Z3 r& h- ~+ s* J8 R( K2 y字串 find 出现在字串 in 里面的位置。如果在字串 in 里面找不到字3 T' [6 }9 ^* ]# M
    串 find,则传回值为 0。
    % C( G: n8 _$ u3 l+ d& L+ ?( G例如:4 }: |& b" P$ M& X# u
    print index("peanut","an")
    2 W. \+ O+ E' c/ @- r2 r会印出 3。
    8 s9 r4 Q: a, J  L' b3 @length(string)
    , M- n7 i& k) ^求出 string 有几个字元。
    5 O4 U; t- V4 H, V; \6 k. r例如:
    # t; P& q8 X7 X( ^  @3 \9 @length("abcde")
    2 \: z7 y+ e9 J; B! N7 a+ f是 5。! b* T0 v+ L# s  w% r
    match(string,regexp)
    , N# V0 e, r) a! {9 K$ ?0 Y. lmatch 函式会在字串 string 里面,寻找符合 regexp 的最长、最靠3 `; Q" f# L) Z6 \
    左边的子字串。传回值是 regexp 在 string 的开始位置,即 index
    3 ]% x' V8 d/ W1 g$ m& R9 A9 p值。
    6 c2 ^" T. n* e4 r2 n& _( {/ Xmatch 函式会设定内在变数 RSTART 等於 index,它也会设定内在变, c: @2 d& {6 X2 y2 T7 `4 v
    数 RLENGTH 等於符合的字元个数。如果不符合,则会设定 RSTART 为; ^& s3 t1 Q) i- I0 A) R
    0、RLENGTH 为 -1。
    6 }" t9 z6 C/ ~: Nsprintf(format,expression1,...)7 x* K4 }  {- s& G/ x8 w
    举 printf 类似,但是 sprintf 并不印出,而是传回字串。1 k  {  ^. v. ^4 D9 ~6 t
    例如:9 z3 \5 X# p( O% E0 i) e& ]+ ^
    sprintf("pi = %.2f (approx.)',22/7)4 l7 d" |) g2 Y2 p/ t; ?
    传回的字串为"pi = 3.14 (approx.)", g: j  P& X8 J+ u
    sub(regexp, replacement,target)
    7 ?! u9 ~" W3 E- `# b在字串 target 里面,寻找符合 regexp 的最长、最靠左边的地方,
    & m3 z1 k0 R2 M以字串 replacement 代替最左边的 regexp。
    2 z% `; U, b1 N. C例如:) E+ W% b6 j" P' g  c- ^% i
    str = "water, water, everywhere"3 W0 D# W- y7 }
    sub(/at/, "ith",str)2 _. j, u3 `. k1 L, v# D! K
    结果字串str会变成
    6 k9 q# H3 W" R4 N"wither, water, everywhere"
    " I  B; g5 ~% y  L  Pgsub(regexp, replacement, target)
    / K) g+ F) P& Y7 L8 Qgsub 与前面的 sub 类似。在字串 target 里面,寻找符合 regexp 的  H! R2 c0 t; F  G" W
    所有地方,以字串 replacement 代替所有的 regexp。9 W! F8 \& A; Y% P6 F$ N
    例如:0 ^% f4 N/ ?# P/ T. }9 J
    str="water, water, everywhere"
    $ e0 [# V, E, A8 Lgsub(/at/, "ith",str)8 c  f* `5 ]. H* X* `9 N* R
    结果字串str会变成7 T8 o9 K8 h' Z# r  c4 @& P( M7 \0 ?
    'wither, wither, everywhere"" k0 Q: |$ E: `  l) R  v
    substr(string, start, length)5 J; k" m) l2 c
    传回字串 string 的子字串,这个子字串的长度为 length 个字元,$ n8 f8 i9 h  J! i9 E# f" G' Y
    从第 start 个位置开始。4 h: N8 w2 ~, G3 e
    例如:
    : E% F: w/ q! F) l2 U* tsubstr("washington",5,3)
    " z) Q& M# F( R/ v  O7 J传回值为"ing"
    & c% X! |) l; N" u" |( J# _如果 length 没有出现,则传回的子字串是从第 start 个位置开始/ H; Z! ~$ {: c4 Q
    至结束。
    : l% a3 p4 O5 A7 r5 l例如:
    , D, R6 L  D# ^, ?substr("washington",5)
    % `. s! h6 d/ B1 z% m- H传回值为"ington"
    + U) I$ O5 J. [; m5 e. qtolower(string)
    8 r" A, U& e0 O) R: R2 t将字串string的大写字母改为小写字母。2 G0 `( F2 R3 v' F  _& h4 }5 w. o! L& Z
    例如:
    3 J2 c5 ~" A) ]7 h* Etolower("MiXeD cAsE 123")  |/ L' r+ V$ u, d. d
    传回值为"mixed case 123"
    , w# O' |: }* i4 z6 x  N: Ztoupper(string)
    9 C6 @: G$ C, n/ z% c) r* M将字串string的小写字母改为大写字母。
    / j; |- g  m  O例如:2 Q& ~3 A. x* b2 M' Q
    toupper("MiXeD cAsE 123")
    8 l' b7 f) m2 G; x! G$ ^9 n5 X) k传回值为"MIXED CASE 123"
      U( r" c- s: V! t" V: C& J  @$ D0 \/ H
    8.3 输入输出的内建函式, @5 }2 Z/ C. j" {7 x5 H* h& r
    close(filename)
    1 m8 c2 \3 A$ i3 ?. R将输入或输出的档案 filename 关闭。
    2 Q4 b! p1 b5 D3 Osystem(command)
    ! Y1 {  e6 ?( S此函式允许使用者执行作业系统的指令,执行完毕後将回到 gawk
    ) f4 N+ F1 i6 _4 v) j程式。+ u8 ]" w8 Y% H7 z; U6 i$ B2 S
    例如:
    : L7 I8 `/ \( D- a3 ^  uBEGIN {system("ls")}* L( f  |- ]5 z

    & j  W! Z: `# y5 D& B1 D第九章 使用者定义的函式(User-defined Functions)$ W3 e# N/ I+ s* {5 m
    复杂的 gawk 程式常常可以使用自己定义的函式来简化。呼叫使用  v7 S* `& w$ G  k# p
    者定义的函式与呼叫内建函式的方法一样。9 k' K- h% }4 W+ q/ K4 W
    9 a: q# Q: @2 L2 b* z
    9.1 函式定义的格式/ ?1 x( n9 o5 V4 c- j- L7 s1 W; l
    函式的定义可以放在 gawk 程式的任何地方。
    / }9 I/ \2 \( w# n$ W' c3 {一个使用者定义的函式其格式如下:1 T- P# T# j4 y
    function name (parameter-list) {
    8 K+ R$ R: _) l: _body-of-function
    2 p7 |2 Z& I7 |" l% u0 M+ z}% m( j1 l" {. K0 u# o
    name 是所定义的函式之名称。一个正确的函式名称可包括一序列的字
    4 J9 X% O0 z1 o+ R母、数字、下标线 (underscores),但是不可用数字做开头。
    ( T+ k3 B; x) X3 O. V% uparameter-list 是列出函式的全部引数(argument),各个引数之
    2 r) ?4 y8 Y# Z( N7 b; P, A" u, }间以逗点隔开。" v5 g9 F8 h; _. V
    body-of-function 包含 gawk 的叙述 (statement)。它是函式定义
    * j$ q- O9 D, e% G$ l* U9 g里最重要的部份,它决定函式实际要做何种事。( S. U- E( L3 F+ `/ i

    7 R' @, g% x$ T4 ~9 A: H" N6 ]% n9.2 函式定义的例子
    5 d" ^$ A5 ]6 W: m( P. `下面这个例子,会将每个记录的第一个栏位之值的平方与第二个1 X7 a8 K0 z/ Y7 o- g* ^
    栏位之值的平方加起来。
      d+ X1 `7 A& _& W, ?{print "sum =",SquareSum($1,$2)}
    8 s7 v! W- B) p5 Z$ F  efunction SquareSum(x,y) {6 T' L# e) |( w! o6 {
    sum=x*x+y*y4 D  w9 [: _9 _8 l; h7 q
    return sum
    % i- ~: q* k3 ~}
    $ C! n0 w5 {/ e0 p4 O& w. P) B( R$ L7 z0 y3 H: }! l. s6 K
    第十章 □例0 ~& N. X8 X2 H7 W7 V; j5 Z
    这里将列出 gawk 程式的一些例子。; B" C: F; \7 C7 o( k
    gawk '{if (NF > max) max = NF}; |+ V* y- k% d7 @0 e" V
    END {print max}', {, h6 O) X! u6 @( e- J% h
    此程式会印出所有输入行之中,栏位的最大个数。" B5 g- _8 O, {
    gawk 'length($0) > 80'2 ^, y# E; n. w% P0 [  w" S
    此程式会印出一行超过 80 个字元的每一行。此处只有 pattern 被; x0 ]+ s' a8 _9 G  T7 B9 h
    列出,action 是采用内定的 print。. i# B* H2 L! z- o
    gawk 'NF > 0'4 F7 S& t# _( c# T% f* R; E# [
    对於拥有至少一个栏位的所有行,此程式皆会印出。这是一个简" C  o5 L; ^: @8 f" i- m: d  m
    单的方法,将一个档案里的所有空白行删除。
    0 g  `( w6 I! l* m; wgawk '{if (NF > 0) print}'  _- w5 B$ O9 ~3 B0 U
    对於拥有至少一个栏位的所有行,此程式皆会印出。这是一个简
    " C( K$ r& N& @单的方法,将一个档案里的所有空白行删除。
      M$ f1 g- V# @2 j& L$ k: Xgawk 'BEGIN {for (i = 1; i <= 7; i++)
    1 W  o7 D9 H" X# }print int(101 * rand())}'
    ! Z0 ~  G# h: ?8 I3 I$ u4 [# Q此程式会印出□围是 0 到 100 之间的 7 个乱数值。
    6 F' f( \( A" Y' r$ J2 L5 D& m1 Bls -l files | gawk '{x += $4}; END {print "total bytes: " x}'
    - R( z. o9 Z4 _# w0 I% v+ e此程式会印出所有指定的档案之bytes数目的总和。
    : U' n: h" s( j- z6 j% u) ~7 ^expand file | gawk '{if (x < length()) x = length()}5 Q4 B+ Y1 S2 C
    END {print "maximum line length is " x}'
    ) g( |+ a& |+ `2 |. o; B8 W此程式会将指定档案里最长一行的长度印出。expand 会将 tab 改
    7 \/ b5 R0 Z7 T3 U( @# b+ g3 A: L成 space,所以是用实际的右边界来做长度的比较。
    9 Z; ~7 a/ o  t( w% O; ngawk 'BEGIN {FS = ":"}+ ~$ q% }$ V9 V) x# x5 o
    {print $1 | "sort"}' /etc/passwd4 K2 S8 H% b- |6 ^  x' ^/ g0 L
    此程式会将所有使用者的login名称,依照字母的顺序印出。
    ( K% T3 h3 i- U9 c! R' Mgawk '{nlines++}
    . [  H' c2 Q' `: FEND {print nlines}'& W& h; u! [$ ^! g
    此程式会将一个档案的总行数印出。+ ?  C$ M2 D  P" S' T
    gawk 'END {print NR}'0 B8 E7 t+ v5 `  T  l
    此程式也会将一个档案的总行数印出,但是计算行数的工作由gawk4 x  T; S3 p! A: }  S
    来做。
    % d, v" P& l6 n1 P, |gawk '{print NR,$0}': Q) b. N$ a; v5 i
    此程式印出档案的内容时,会在每行的最前面印出行号,它的功
      o) w$ m& M9 i+ c# b能与 'cat -n' 类似。7 Y. K6 n; ~# e1 h( z# W& Y" d
    ) U6 a" \: _5 A/ ^7 r* `
    第十一章 结论! h: {4 G. V$ D2 y$ v
    gawk 对於资料的处理具有很强的功能。它能够以很短的程式完成
    6 D* {/ E5 v2 p2 L( a' o% M想要做的事,甚至一或二行的程式就能完成指定的工作。同样的一件
    6 I- L) [; m: A工作,以 gawk 程式来写会比用其它程式语言来写短很多。
    ; L' v# [1 H/ {& i; ^' C  ~gawk 是 GNU 所做的 awk,它是公众软体(Public Domain) 可免费使* P8 A9 o7 R+ C9 e
    用。
    "真诚赞赏,手留余香"
    还没有人打赏,支持一下
    楼主热帖

    相关帖子

    帖文化:【文明发帖 和谐互动】 社区精神:【创新、交流、互助、共享】

    该用户从未签到

    尚未签到

    发表于 2008-6-12 18:18:47 | 显示全部楼层
    "gawk 对於资料的处理具有很强的功能" : Z9 B7 J! x$ w0 x0 q- G
    还是不太懂,是一个文本文件的批量处理工具吗?
    "真诚赞赏,手留余香"
    还没有人打赏,支持一下
    帖文化:【文明发帖 和谐互动】 社区精神:【创新、交流、互助、共享】
    您需要登录后才可以回帖 登录 | 立即加入

    本版积分规则

    招聘斑竹

    小黑屋|手机版|APP下载(beta)|Archiver|电力研学网 ( 赣ICP备12000811号-1|赣公网安备36040302000210号 )|网站地图

    GMT+8, 2026-10-9 21:56

    Powered by Discuz! X3.5 Licensed

    © 2001-2026 Discuz! Team.

    快速回复 返回顶部 返回列表