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

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

Gawk手册

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

    连续签到: 1 天

    [LV.1]初来乍到

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

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

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

    ×
    GAWK; ?# @2 V5 q6 L  k+ x3 [8 u( G
    第一章 前言2 j4 w9 z6 B/ ~8 T' e; o
    第二章 简介/ q. o* V9 T0 n/ O
    第三章 读取输入档案9 h0 @5 x$ `5 A) W
    第四章 印出' p' }6 q) d& W4 ~8 X8 J
    第五章 Patterns
    $ f% v6 ^( E  c第六章 算式(Expression)作为Actions的叙述( A/ j& r# ?6 m
    第七章 Actions里面的控制叙述4 y. C  K1 B5 v1 [/ j1 P
    第八章 内建函式(Built-in Functions)& y: R- B, o- L; g5 @( N+ G
    第九章 使用者定义的函式% f5 f8 Y  u5 \6 i
    第十章 □例
    2 W  s( j4 ^% L# T! t* R第十一章 结论  |6 q! w$ G' ^0 B' V9 r

    - C% A: T; T: }2 f=======================================
    - C' X. W$ L4 N8 N第一章 前言: w0 ?, r! ^8 ]! l$ T2 N' D
    awk 是一个程式语言,对於资料的处理具有很强的功能。对於文
    , ?& R/ }' Z. ^+ L8 I字档里的资料做修改、比对、抽取等的处理,awk 能够以很短的程式
    . o  w; g" q* u8 g, o$ v轻易地完成。如果使用 C 或 Pascal 等语言写程式完成上述的动作,
    ) x  e  [& c/ y5 o  A会不方便且很花费时间,所写的程式也会很大。
      r( e. ~! @4 s; E/ W/ f% Y1 b- mawk 能够依照使用者的定义格式来分解输入资料,也可依照使用: |/ G' K+ W9 y- ?3 R3 F
    者定义的格式来印出资料。
      @- p% e# n- G7 U% d# f: K% L& N; hawk 名称的由来是由它的原始设计者的姓氏之第一个字母而命名
    ( Y5 Q: _4 h" B8 L:Alfred V. Aho, Peter J. Weinberger, Brian W. Kernighan。1 n5 r2 b) X+ s! O; Q, b5 M
    awk最初在1977年完成。一个新版本的awk在1985年被发表,它的功能5 I1 N6 |# Z: T3 L; t9 r  \( D+ q
    比旧版本增强不少。& Q9 L0 R: S- v# O2 D/ \; y0 d' T
    gawk 是GNU所做的 awk,gawk 最初在1986年完成,之後不断地/ k, X" ^! v+ E
    被改进、更新。gawk 包含 awk 的所有功能。& T: B& O8 G0 A7 q- s8 i' M- T
    往後的 gawk 将以下面的2个输入档案来做例子说明。
    ) S2 ]8 x: i" f$ W- V2 M9 M1 {档案'BBS-list':
    9 u% R8 G- \' S2 K4 Caardvark 555-5553 1200/300 B
    4 I4 }& `& r" c% p' galpo-net 555-3412 2400/1200/300 A
    & b: L/ J+ W! X6 n: @* Z) J3 @barfly 555-7685 1200/300 A5 S. R' p8 E4 x0 ~9 s4 [
    bites 555-1675 2400/1200/300 A
    ! }( c* J4 ]7 D  T7 N6 J# ~0 O) Ucamelot 555-0542 300 C% @" X% [. V) y" F" I! b
    core 555-2912 1200/300 C1 S4 z/ }! D  F5 Z: o2 r1 H$ x
    fooey 555-1234 2400/1200/300 B
    7 x, b, y6 H: j# E# `foot 555-6699 1200/300 B2 Y2 E6 Y5 h6 k5 [7 m
    macfoo 555-6480 1200/300 A
    ; {: a: N9 r9 E' t6 f  y* Zsdace 555-3430 2400/1200/300 A1 o$ u  V! |. W. t$ @
    sabafoo 555-2127 1200/300 C
    : b; t+ T6 w; O: b: C档案'shipped':
      p: l$ M8 U5 p4 u' sJan 13 25 15 115
    0 I: b8 t- H! EFeb 15 32 24 226% \, [6 B  R% H3 a$ [) x
    Mar 15 24 34 2284 E4 `# ]  w% L# M. V  k
    Apr 31 52 63 420
    * I. j, b2 b+ n0 z, E* EMay 16 34 29 208% K' |: s* R5 l1 t' u7 M
    Jun 31 42 75 492
    " L3 B6 I) f) o( m# \$ ^Jul 24 34 67 4363 m9 a6 h" x9 M& d+ D
    Aug 15 34 47 316/ h$ E/ z8 F8 R, R, F( g
    Sep 13 55 37 277
    . i' j( i  q+ a5 O' eOct 29 54 68 525
    ) N1 V7 U" j: {' L; zNov 20 87 82 577
    - _1 M( z4 u; ~; P" EDec 17 35 61 4015 X( ~3 v3 R" o) N4 d
    Jan 21 36 64 620+ n3 d3 N1 d# I3 o( M2 G, `7 W6 S
    Feb 26 58 80 652
    5 W; X, Z6 W; m, I/ MMar 24 75 70 495# P  F" T$ J! ?$ _. k8 \/ Q
    Apr 21 70 74 514
    " W0 N; b; U; O+ ~- f4 I5 n9 t
    % u$ W% |4 i; X  G第二章 简介9 y8 {/ V3 b" z. j' |9 h" y
    gawk 的主要功能是针对档案的每一行(line)搜寻指定的 patterns
    & p8 k. O& e% L3 ^。当一行里有符合指定的 patterns,gawk 就会在此一行执行被指定; E& V7 n& E, i2 L+ b6 o( ^
    的 actions。 gawk 依此方式处理输入档案的每一行直到输入档案结. I' y  |/ h; m$ q$ \4 W: K& C& a
    束。% j+ S1 z; k# p9 ~8 v1 K
    gawk 程式是由很多的 pattern 与 action 所组成,action 写在
    7 Y, A, o  {% j2 R' E大括号 { } 里面,一个pattern後面就跟著一个action。整个 gawk 程  C5 t% a& T( M
    式会像下面的样子:
    4 f- W/ v+ D( ypattern {action}
    $ Y% Z1 X+ ~3 q7 n! G1 F, ipattern {action}
    9 q% }2 Y2 }( h9 D5 S在 gawk 程式里面的规则,pattern 或 action 能够被省略,但
    5 ~) X2 C' s' m; F, n8 y是两个不能同时被省略。如果 pattern 被省略,对於输入档里面的
    5 e; h3 h) j2 O) ~0 G# d每一行,action 都会被执行。如果 action 被省略,内定的 action7 d2 {9 r2 V, [
    则会印出所有符合 pattern 的输入行。
    9 j. ?% V2 m  j. T
    $ v- \1 T# @: B' P" P2.1 如何执行gawk程式
    ; G* N+ l* s1 o$ ?# R; c基本上,有2个方法可以执行gawk程式。/ z) m: B, E3 \( g1 J4 r
    □如果 gawk 程式很短,则 gawk 可以直接写在 command line,如下所示:
    - @- x% t  Z- C- Lgawk 'program' input-file1 input-file2 ...: _9 E! x' ]$ ~/ N, V+ D2 K
    其中 program 包括一些 pattern 和 action。
    ) h0 V3 O( C+ r, _1 B□如果 gawk 程式较长,较为方便的做法是将 gawk 程式存在一个档案,5 C; q* ?" G' L! P+ d7 Z: B& [
    即 patterns 与 actions 写在档名为 program-file 的档案里面,执行
    4 j& Q# h" z0 `! Y! Xgawk 的格式如下所示:* |* l: @4 {9 }/ a" f: S
    gawk -f program-file input-file1 input-file2 ...1 f2 _9 Z* B" d- [( r0 M% O
    gawk 程式的档案不止一个时,执行gawk 的格式如下所示:; o! K* Y  I+ k' x* Z( d- j' n5 r
    gawk -f program-file1 -f program-file2 ... input-file11 _3 B6 \! a$ X  C* @, H; M
    input-file2 ...
    0 J+ ?# y; [3 D& o6 m7 h+ Y) S- l- m/ E6 r
    2.2 一个简单的例子; W1 C, H1 y8 n. U0 M$ c
    现在我们举一个简单的例子,因为 gawk 程式很短,所以将 gawk 程1 Q8 I& C* i! L) _4 F2 B& w
    式直接写在 command line。
    0 t/ K" X" i2 ?gawk '/foo/ {print $0}' BBS-list
    , B$ z: K6 }, t& B1 `实际的 gawk 程式为 /foo/ {print $0}。/foo/ 为 pattern,意思为搜. u: }) {' b0 [  x
    寻输入档里的每一行是否含有子字串 'foo',如果含有 'foo' 则执行 action。
    1 f: o4 G3 p3 eaction 为 print $0,是将现在这一行的内容印出。BBS-list 是输入的档案。
    6 ?. W! Z) R! D) B5 h执行完上述指令後,会印出下面的结果:
    $ F  F4 S% h8 ifooey 555-1234 2400/1200/300 B3 C7 h. ~: c# C. l. o; j. \1 Z- y
    foot 555-6699 1200/300 B
    8 {8 _  }" y' Amacfoo 555-6480 1200/300 A7 ^' d/ n6 {' J6 j6 ^
    sabafoo 555-2127 1200/300 C' K( q0 H  [% h5 D. J/ x( ~

    : Z9 |" M) I) X. b" Z0 {2.3 一个较复杂的例子
    * h8 d0 u) x2 n  @gawk '$1 == "Feb" {sum=$2+$3} END {print sum}' shipped
    2 \! |0 n- ^. ]6 a6 F0 T$ b! l现在这个例子会将输入档 'shipped' 的第一个栏位与 "Feb" 做比较
    5 A0 ?4 h8 Q7 w: ?, C/ u,如果相等,则其对应的第2栏位与第3栏位的值会被加到变数 sum。  R% G5 {+ E+ S
    对於输入档的每一行重复上述的动作,直到输入档的每一行都被处理
    9 x6 N9 h, h& F; c2 m: u过为止。最後将 sum 的值印出。END {print sum} 的意思为在所有的输
    $ e" D( ?' Y, M) O9 C入读完之後,执行一次 print sum 的动作,也就是把 sum 的值印出。
    . c& e0 N/ w# y' w7 m, P下面是执行的结果:& {& _* E/ g' U& S8 L
    84
    9 R2 }  `: i( ~8 q( T3 x8 v
    4 E0 Q0 p! D+ U  M第三章 读取输入档案
    ' Z4 |4 n* W" d5 X; x+ @gawk的输入可以从标准输入或指定的档案里读取。输入的读取单' b: |; i8 H8 j  B& C
    位被称为”记录”(records),gawk 在做处理时,是一个记录一个记* [3 L% B4 }4 Y* c$ K
    录地处理。每个记录的内定值是一行(line),一个记录又被分为多个. g6 B2 r' w$ v. A& P
    栏位(fields)。, s$ u3 G* H5 c+ ?9 i0 C
    ! T9 [. r+ G  Y+ i% B* k6 P! p! E  i
    3.1 如何将输入分解成记录(records)
    6 Q2 K  K2 w: v2 M, ~* Agawk 语言会把输入分解成记录(record)。记录与记录之间是以7 Z( j" f3 F- z1 w* k& D, Y, P
    record separator 隔开,record separator 的内定值是表示新一行的
      U! C6 {0 h+ P% A8 P字元(newline character),因此内定的 record separator 使得文字
    ) P6 ]5 n# E$ Z的每一行是一个记录。
    7 ]( K5 I6 ]+ Y$ A8 V! G+ k7 \1 Urecord separator 随著内建变数 RS 的改变而改变。RS 是一个字串,9 B8 G, Z% V: t: [1 U1 H; F( B% Q
    它的内定值是"\n"。仅有 RS 的第一个字元是有效的,它被当作 record
    3 W: m% t: X- P. b, N  mseparator,而 RS 的其它字元会被忽略。0 u  Z2 b! I$ H/ j& M1 H# U
    内建变数 FNR 会储存目前的输入档案已经被读取的记录之个数。内7 W$ a: u3 q" S' l; C7 ^6 P
    建变数 NR 会储存目前为止所有的输入档案已经被读取的记录之个数。8 b! m8 V, F: R9 C0 N

    : U7 y* t( a2 C5 t- y0 ]3.2 栏位(field)
    $ O; P" c3 I. m, agawk 会自动将每个记录分解成多个栏位 (field)。类似於字在一
    % Q! n" b8 R: m* _* W! C% k行里面,gawk 的内定动作会认为栏位之间是以 whitespace 分开。在
    ' c" }8 S; `# j3 G  |  A% {gawk 里,whitespace 的意思是一个或多个空白或 tabs。
    9 z- E  G9 @1 n. l  ~( z5 X, ~& I在 gawk 程式里面,以'$1'表示第一个栏位,'$2'表示第二个栏位. N; A1 Q( F  ?9 f: ~; J/ T
    ,依此类推。举个例子,假设输入的一行如下所示:2 ~. \- b3 ~; x
    This seems like a pretty nice example.) \8 U6 t! ?7 @9 Q. i
    第一个栏位或 $1 是'This',第二个栏位或 $2 是 'seems',依此类推。( y1 s2 ?0 a) ?+ r
    有个地方值得特别注意,第七个栏位或 $7 是'example.'而非'example'。
    5 T/ j! n7 ~/ s- Y& @不论有多少栏位,$NF 可用来表示一个记录的最後一个栏位。以
    ( W5 y5 `' \3 N% e上面的例子为例,$NF 与 $7 相同,也就是'example.'。
    8 T6 z1 Z) M1 c* d% rNF 是一个内建变数,它的值表示目前这个记录之栏位的个数。1 j/ ?; B8 {* {5 {7 i- `# \) [+ z' J( E9 r
    $0,看起来好像是第零个栏位,它是一个特例,它表示整个记录。5 Z! p( H1 _4 h
    下面是一个较复杂的例子:
    8 @1 K5 o# |+ R7 cgawk '$1~/foo/ {print $0}' BBS-list7 W' [) F! G$ e7 E) Q6 F" i) l; b
    结果如下:
    4 L5 [& n& a. Q1 s$ w2 p! Qfooey 555-1234 2400/1200/300 B: f4 Z) }8 g, @4 r: ]$ P
    foot 555-6699 1200/300 B7 }) b, y% X# V, _9 ?5 t
    macfoo 555-6480 1200/300 A
    ! h" o; i  t* i! _sabafoo 555-2127 1200/300 C1 e2 T  o- j* H
    这个例子是把输入档'BBS-list'的每个记录的第一个栏位作检查,如
    % Q* `4 E8 a. a8 W( F% L$ d: n果它含有子字串'foo',则这一个记录会被印出。8 `* U: a0 e" w! j# n

    ( ^" Y$ _' W4 @* v, O3.3 如何将记录分解成栏位, U9 |1 z8 w2 Y! b- ^8 |6 Q
    gawk 根据 field separator 将一个记录分解成栏位。field sepa-* R1 h' N& W1 A) M; [4 H; H
    rator 以内建变数 FS 表示。) P* F& _6 x; P% t& V% f+ R
    举个例子,假如 field separator 是'oo',则下面的行:9 N- E0 h  e2 C% @
    moo goo gai pan6 g4 D$ U# r  R$ V# F
    会被分成三个栏位:'m'、' g'、' gai pan'。* t6 _: y$ O! b. `
    在 gawk 程式里,可以使用'='来改变 FS 的值。例如:
    . H% Q; S: z, W2 A7 Z, tgawk 'BEGIN {FS=","}; {print $2}'
    ( k+ m, Z8 [) F& G( w" b9 S输入行如下:& K- n" @4 d+ P9 U8 c& o: u8 P7 I
    John Q. Smith, 29 Oak St., Walamazoo, MI 42139
    . \) m. C/ E- m. O6 }4 S9 W) c$ p执行gawk的结果将印出字串 ' 29 Oak St.'。BEGIN 後面的 action 会在6 o* s! J. l) d; j
    第一个记录被读取之前执行一次。: @" I! X$ ]9 L/ ^, D
    . c: |/ A* B( g+ n4 r; w
    第四章 印出
    6 q3 u9 f% Q, U! z/ o+ m8 ]) R在gawk程式里,actions 最常做的事就是印出(printing)。简单
    6 D: f! q# I! [( @的印出,使用 printe叙述。复杂格式的印出,使用 printf 叙述。
    ' @6 i. E& h* @7 b* K
    , n3 w& V$ Z& t. L4.1 print叙述, M# v8 F" m& n' ^( }* y
    print 叙述用在简单、标准的输出格式。叙述的格式如下所示:% h  q. Q/ F8 @- D  p3 |
    print item1, item2, ...# B, [6 Y: Z8 I
    输出时,各个 item 之间会以一个空白分开,最後会换行(newline)。
    9 C! q, f8 a6 H: |! N% L: y7 y如果 'print'叙述之後没有跟著任何东西,它与'print $0'的效
    ( G* l! Z6 g0 M- Y# s5 [/ F. k果一样,它会印出现在的记录(record)。要印出空白行可使用'print
    - [7 z+ `  W7 B- B  n! m""'。 印出一段固定的文字,可用双引号将文字的两边括起来,例如
    - Q2 G( t/ ^% E3 l  u+ y* {'print "Hello there"'。
    5 X# V% `: T! z9 E' W这里是一个例子,它会把每个输入记录的前二个栏位印出:, Z9 v7 ~& l# D7 w+ t  {+ ~
    gawk '{print $1,$2}' shipped& l2 B6 h* u( b6 R
    结果如下所示:5 M1 [% a6 E* P% ?# ^6 \
    Jan 13! o1 Q8 F' x/ M/ g6 |9 z9 }0 I) r
    Feb 156 i2 b- ~' f, W5 b* w1 ?' k: m7 i. x
    Mar 15: o( O. \2 v: [: V9 L4 @' c
    Apr 31
    : U8 z- J# a8 A! \9 l5 NMay 16) N* L# o% L! f9 \
    Jun 31! \7 X" a) p5 n* G. Y' Z
    Jul 24$ ]+ }# b; K) N' i9 `
    Aug 15
    3 {0 r/ o9 J, u' E) j: x( WSep 13) k. B% w* @) N
    Oct 29
    ( V0 B  Z" V& iNov 20
    0 C" k: z! t6 i. [  ~; r* r, VDec 17) ]" d  g: }+ y, Y: i2 }4 Y0 }
    Jan 21
    : Z9 [# Z( {" U7 c; w; e6 SFeb 26; f; l5 c' U7 T
    Mar 24) v9 `+ D! v0 i
    Apr 21) t6 w& Z( ]& p" l$ S2 l5 ?

    + O1 @& l; E( V/ _. c" O4.2 Output Separators
    * L6 E9 N/ J5 z* d. [6 Z5 P前面我们已提过如果 print 叙述包含有多个 item,item 之间
    ( P, W5 R# O3 R9 j! J6 B5 ~/ P) j用逗点分开,则印出时各个item会被一个空白隔开。你能够使用任何
    : M* b8 `; k# V! q8 e& [的字串作为 output field separator,可以经由内建变数 OFS 的设
    3 z9 w+ M3 b# Z+ p3 i1 K定来更改 output field separator。OFS 的初始值为" ",即一格的
    6 h1 e  Z: u; Q: K0 ^) R空白。
    ( S* v+ P  p$ [整个 print 叙述的输出被称为 output record。print 叙述输5 i7 F0 \& b2 J
    出 output record 之後,会接著输出一个字串,此字串称为 output' L4 i$ a. R: y2 f8 S" {; ~
    record separator。内建变数 ORS 用来指明此字串。ORS 的初始值
    3 T# E" v* S9 L( o- ]5 ?5 W  h4 [! l为 "\n",也就是换行。
    - z$ s' k4 ?' a! O& R6 m, c下面这个例子会印出每个记录的第一个栏位和第二个栏位,此二/ z6 s7 W  W# q% W
    个栏位之间以分号';'分开,每行输出之後会加入一个空白行。( f5 d2 O- b1 O6 I; g
    gawk 'BEGIN {OFS=";"; ORS="\n\n"} {print $1, $2}' BBS-list
    1 b1 L/ ?' c2 r2 L结果如下所示:
    % u: O; R8 a6 R3 K  raardvark;555-5553
      `; \% U3 q0 d  {1 \" \8 Z: balpo-net;555-34121 `+ t5 Z& O: S/ V: V* l
    barfly;555-7685
    " M) k& u& v- T8 f: Wbites;555-1675
    . S; o3 _2 _% p; B; Zcamelot;555-0542% c% q, |! ~5 s
    core;555-2912( M) e1 b. D' i1 r: D6 L$ R+ k
    fooey;555-1234
    & Z3 f, H: B$ t; ]8 m& z/ Ifoot;555-6699. y9 Y; [: Q2 u. @1 ^
    macfoo;555-6480
    6 q  z( |$ g+ Dsdace;555-3430% N+ h2 m- [. s: b' ^% Z
    sabafoo;555-2127
    1 r9 ]4 K0 q# s! v2 n6 ]
    4 Z+ z2 E7 U" v- C3 W( _2 W& z) s4.3 printf叙述
    # I) @" W2 ]9 q. l( hprintf 叙述会使得输出格式较容易精确地控制。printf 叙述可以+ F; _* ^3 g9 O. x/ z1 _
    指定每个 item 印出的宽度,也可以指定数字的各种型式。4 v& s/ D9 m  E" W5 X7 Q  z
    printf 叙述的格式如下:# H+ t* X  @5 |# g. G' g
    printf format, item1, item2, ...- O: ~9 f1 N$ j1 z$ [; p
    print 与 printf 的差别是在於 format, printf 的引数比 print3 S& {6 u. F: H4 K
    多了字串 format。format 的型式与 ANSI C 的 printf 之格式相同。7 N' K% s' C) L1 U2 d, ]  f
    printf 并不会做自动换行的动作。内建变数 OFS 与 ORS 对 printf 叙
    : w# U1 k. y- |$ E& A/ a& ~述没有任何影响。
    . J7 x* a& }6 w2 w; v' E格式的指定以字元'%'开始,後面接著格式控制字母。* n' t! G; @- Y. ^1 Y
    格式控制字母如下所示:: T/ E( b6 S; M; c& g: a
    'c' 将数字以 ASCII 字元印出。
    % Q4 k4 k4 h% S  [* E例如'printf "%C",65'会印出字元'A'。
    / q5 \3 _2 Z4 H+ X% D, S'd' 印出十进位的整数。
    . _# {4 g1 T/ q2 j1 r; E  l2 x'i' 印出十进位的整数。9 a/ e5 m- _( j) U
    'e' 将数字以科学符号的形式印出。
    2 ^7 W5 J1 j; j例如( \6 w; y% z, K$ S
    print "$4.3e",1950
    4 L7 [/ W. I7 U: H' f结果会印出'1.950e+03'。/ _1 B6 i2 t5 r9 b  S
    'f' 将数字以浮点的形式印出。) k8 k) U9 ]1 ~
    'g' 将数字以科学符号的形式或浮点的形式印出。数字的绝对值如果
    ( I+ w% J* z& R: _大於等於0.0001则以浮点的形式印出,否则以科学符号的形式印" w0 o  ~/ |* z' U3 g2 H
    出。0 w3 |; i, x+ r* ^
    'o' 印出无号的八进位整数。" M0 F" @1 ^0 ^$ e6 d7 f
    's' 印出一个字串。4 X! W. q3 P. d
    'x' 印出无号的十六进位整数。10至15以'a'至'f'表示。+ ~7 @7 G$ I+ r# B
    'X' 印出无号的十六进位整数。10至15以'A'至'F"表示。
    ) f! a& p. t8 E'%' 它并不是真正的格式控制字母,'%%"将印出"%'。8 T. N; l! K# n. @; X
    在 % 与格式控制字母之间可加入 modifier,modifier 是用来进一( w' s6 F, i. ~: @8 I+ \! A' p
    步控制输出的格式。可能的 modifier 如下所示:
    % `0 v$ L5 N! m. z; k) K'-' 使用在 width 之前,指明是向左靠齐。如果'-'没有出现,则会在  f8 [  Y& H8 P
    被指定的宽度向右靠齐。例如:' h9 C3 d0 u5 h& o6 ~* R
    printf "%-4S", "foo"3 ?& K& x; E7 `( m, x
    会印出'foo '。
    6 \8 Z8 n; Y$ t/ K* V'width' 这一个数字指示相对应的栏位印出时的宽度。例如:
    8 G- \2 V3 |2 @8 B# uprintf "%4s","foo"7 ~: F. c; s7 l+ {3 P
    会印出' foo'。" J: J: [) q" ?- L1 Z+ F0 h
    width 的值是一个最小宽度而非最大宽度。如果一个 item 的) S; C# \6 i! r
    值需要的宽度比 width 大,则不受 width 的影响。例如/ u, Q# C: ?% h+ ~
    printf "%4s","foobar"& R% J/ p; v) G& s' K$ [
    将印出'foobar'。4 \3 i# C+ m, |. |( u
    '.prec' 此数字指定印出时的精确度。它指定小数点右边的位数。如
    5 p; _" c% g5 O  K3 P- Z* ^3 \果是要印出一个字串,它指定此字串最多会被印出多少个字
    4 i, i4 D3 @* v元。- Y4 k% x: w! h- L4 I

    " ?1 X( K3 W" h5 T9 I+ V% ?第五章 patterns7 b# I2 A# F5 E% Y
    在 gawk 程式里面,当 pattern 符合现在的输入记录(record),其
    & d. R: q+ g) Z/ H; q! @/ a相对应的 action 才会被执行。
    $ S5 J7 U# b& P: F& m/ j( [8 j5 D% }% o& U. Q# t
    5.1 Pattern的种类- u5 G2 G& C9 c2 v* E, D
    这里对 gawk 的各种 pattern 型式作一整理:
    3 m. A$ D6 n2 w* E/regular expression/. i7 c& `  N6 J; R; h3 G( G
    一个 regular expression 当作一个 pattern。每当输入记录 (
    ( X* q6 D/ b* u* N0 [3 rrecord)含有 regular expression 就视为符合。
    1 |3 [$ M! G9 m8 ]8 t7 qexpression! Z6 s) n0 B; i3 o3 z/ Y
    一个单一的 expression。当一个值不为 0 或一个字串不是空的,
    , [! d: H5 P2 N0 a则可视为符合。) j8 [  Q4 p8 ?
    pat1,pat2
    / K) @& N) e& u* ]& R一对的 patterns 以逗号分开,指定记录的□围。1 G6 T3 U  a- T( `: A- a6 ]" ]
    BEGIN( R3 s. }& [) x0 a! g6 z
    END( N' n" B/ q9 x3 v* R" J7 S
    这是特别的 pattern, gawk 在开始执行或要结束时会分别执行相
      Y2 c+ J. n+ F5 j对应於BEGIN或END的 action。7 C: w7 y+ i. z1 r+ P. d
    null
    , Y2 S) d- r% r6 _9 z7 y2 p这是一个空的pattern,对於每个输入记录皆视为符合pattern。$ l$ e0 l2 ?6 \8 S2 O' w/ ^

    ' E; t( y( @  Y; {* w5.2 Regular Expressions当作Patterns
    ( |4 S* _4 w5 h% \; U$ o6 L+ K% F7 c" S5 K一个 regular expression 可简写为 regexp,是一种描述字串的方. I6 h" L/ O: K* f  j, q8 Q6 N
    法。一个 regular expression 以斜线('/')包围当作 gawk 的 pattern。
    ; x0 w3 _6 X3 C9 a% X- e/ I如果输入记录含有 regexp 就视为符合。例如:pattern 为 /foo/,
    1 Y* e0 L) T" V0 \* R/ n" o, N对於任何输入记录含有'foo'则视为符合。
    - _. q* Y, Z/ ~0 x& X下面的例子会将含有'foo'的输入记录之第2个栏位印出。$ z* D  C& p- ~: C% I* G
    gawk '/foo/ {print $2}' BBS-list
      n2 J1 Q1 a. h" D8 Q8 z' h结果如下:
      p. {/ X' s8 P( S; q- n/ d555-12343 I5 m1 N- o6 h& b) f
    555-6699
    3 M/ I$ k4 p5 a% S$ Q# Y/ Z) [! C, }555-6480
    7 t" q, ^% B3 L% k( p4 i" J7 u555-2127
    4 I$ c7 Q5 A* @: W5 aregexp 也能使用在比较的算式。6 j" X' A) M6 P1 K% E2 o
    exp ~ /regexp/
    9 X2 Z, u5 E3 l' ]& `/ u如果 exp 符合 regexp,则结果为真(true)。: H8 l1 J# ]. N
    exp !~ /regexp/
    % k& ~1 k6 f3 N6 h) V5 c如果 exp 不符合 regexp,则结果为真。
    # f# o) @4 H7 p' a
    9 z; o+ K& k1 O) l5 o4 c2 ?- c: o5.3 比较的算式当作Patterns. z5 q2 a9 R! v' ~% W, A5 n# c6 r
    比较的 pattern 用来测试两个数字或字串的关系诸如大於、等於
    5 o, o) g8 k! Q% L) A、小於。下面列出一些比较的pattern:
    # {- D) S1 L6 c: o, ox<y 如果 x 小於 y,则结果为真。6 ^' Y' Y/ H3 N2 z4 O+ _. m
    x<=y 如果 x 小於、等於 y,则结果为真。! q% Y- @4 A# ?( P% x- V( o
    x>y 如果 x 大於 y,则结果为真。1 i2 P8 ~6 _( ~6 r+ S5 X7 w; L
    x>=y 如果 x 大於、等於 y,则结果为真。
    ; H: A. R+ o7 J% [" jx==y 如果 x 等於 y,则结果为真。
    3 _3 X, D" ]$ U  I$ w0 B' p* Nx!=y 如果 x 不等於 y,则结果为真。
    ) F: I; ^7 b0 f  f% ux~y 如果 x 符合 regular expression y,则结果为真。5 I6 b! V4 H0 \- v: `
    x!~y 如果 x 不符合 regular expression y,则结果为真。
      a; j2 J9 D4 @* W, F& |& N6 M上面所提到的 x 与 y,如果二者皆是数字则视为数字之间的比较,* M0 p7 _* |) `
    否则它们会被转换成字串且以字串的形式做比较。两个字串的比较,
    . y0 Z# d' y: p* L1 p8 S. @) i会先比较第一个字元,然後比较第二个字元,依此类推,直到有不同
    $ D1 s  p# h9 B% p的地方出现为止。如果两个字串在较短的一个结束之前是相等,则视7 j( u4 C) I) I
    为长的字串比短的字串大。例如 "10" 比 "9" 小,"abc" 比 "abcd" 小。
    # y; _+ s7 |, K: X& V! _3 X7 \" M3 j$ L
    ) H. H0 t6 \: H9 l. m5.4 使用布林运算的Patterns
    4 {! D4 ?, F. U$ t1 R4 Y一个布林(boolean) pattern 是使用布林运算"或"('||'),"及"
    5 W3 O/ a) M5 ^7 M/ a5 g('&&'),"反"('!')来组合其它的pattern。% g$ ^( G! z* Z9 d7 B% }
    例如:6 Q. ^" M( i. l. P* M) M8 U- L$ k  K( e
    gawk '/2400/ && /foo/' BBS-list% D+ z8 d% _( T9 n+ S5 ~0 W
    gawk '/2400/ || /foo/' BBS-list1 D2 Z8 B; T0 q1 P! n  q% s& K
    gawk '! /foo/' BBS-list
    7 A2 \7 v9 x! |! J3 j7 S" z4 f& c6 ^9 R# R) W
    第六章 算式(Expression)作为Actions的叙述
    * T; ]8 e, _7 S0 t  U  N9 T$ g% n算式(Expression) 是gawk程式里面action的基本构成者。3 a9 U- N& H. p+ s9 Z7 I1 Q
    % j5 m" I* p" b! {6 ]7 v
    6.1 算术运算" r7 G8 c  h! Z
    gawk 里的算术运算如下所示:
    2 s+ B, {6 Y( n. I' `7 Z% Vx+y 加
    7 y8 O' ?: D! y' v' Nx-y 减
    6 ]1 H5 ]- g% O2 B& n1 c-x 负
    ; Y2 o# E! O% J2 z0 \2 m+x 正。实际上没有任何影响。+ \7 s' z4 L8 @
    x*y 乘
    + d  q  I* W4 g$ }- @" Rx/y 除. ^9 h9 Y/ B- B& ?# @! `0 P
    x%y 求馀数。例如 5%3=2。) Z3 E: ^) c4 n3 ?
    x^y) W' N. O1 U7 U: P; h
    x**y x 的 y 次方。例如2^3=8。* K% [0 o$ [/ _% u+ b

      }. ?2 Q) D! a( h7 O; ~, e6.2 比较算式与布林算式6 x6 Q( j1 |/ J- M8 M8 P
    比较算式 (comparison expression) 用来比较字串或数字的关系) T1 {- z! w6 h$ v  ~
    ,运算符号与 C 语言相同。表列如下:
    $ i' D( r6 B7 m: Z0 q& h3 ox<y  l9 r( c" L$ s/ A! S
    x<=y
    ) O  V+ w) o9 X1 C7 e$ y4 Bx>y( {" T  @3 j' C. d0 r; N
    x>=y6 q1 c0 i, R) R
    x==y) E: C  m( n9 c# V, w  N
    x!=y  y  b2 {' }3 E- M2 s. `9 t
    x~y
    ; C- V2 p9 M! R: B7 k6 v; kx!~y0 J8 G( j. W# t
    比较的结果为真(true)则其值是 1。否则其值是 0。, }( f& B7 U2 e- V, p, I3 W
    布林算式(boolean expression)有下面三种:
    + k; }6 \5 `) e( x1 q! y$ yboolean1 && boolean2% I& T" |% n' M1 z- Q! o
    boolean1 || boolean2
    6 z0 n  W7 n, F4 b, X! l1 c2 E8 i' [! boolean
    " Y$ O0 l6 Y9 z! B& w! w* d! B/ v* L; o8 b9 T
    6.3 条件算式(Conditional Expressions)
    ) q: Y/ N2 D6 r/ w) ]3 T+ d% f一个条件式算式是一种特别的算式,它含有3个运算元。% J" i! `0 d, U4 ^! E" M
    条件式算式与C语言的相同:
    ) X" H: d* `; G# m  C  U- nselector ? if-true-exp : if-false-exp: L/ c: W4 x9 N& h% u6 @9 E+ j
    它有3个子算式。第一个子算式selector 首先会被计算。如果是真,; u8 V7 L% y+ v
    则if-true-exp会被计算且它的值变成整个算式的值。否则if-false-6 {* g3 M  s  X6 r# V. E
    exp 会被计算且它的值变成整个算式的值。. t% Q( B8 j3 c0 \( d- V
    例如下面的例子会产生x的绝对值:
    3 z& Y- v$ V% ~x>0 ? x : -x
    + o+ b, v# w% Y9 p
    # J( h, F' C  l# D' o2 x) G8 b第七章 Actions里面的控制叙述
    & F( Y7 L# M9 M在 gawk 程式里面,控制叙述诸如 if、while 等控制程式执行的流
    $ P0 B) n- C0 r' y9 L程。在 gawk 里的控制叙述与 C 的类似。
    3 O% @  @) r8 t很多的控制叙述会包括其它的叙述,被包括的叙述称为 body。假( ^" l& ^  Q2 ?' Q; \: h. F
    如 body 里面包括一个以上的叙述,必须以大括弧 { } 将这些叙述括起
    + i. M" s. m& p$ b7 X4 l2 G! {6 @- U来,而各个叙述之间需以换行(newline)或分号隔开。
    & @; C$ n8 m; I
    ; o, _" k$ ~9 ]8 U7.1 if 叙述
    0 d% k6 p# U9 f" T# u, P' Tif (condition) then-body [else else-body]  e/ ]9 V% |! \4 T/ m
    如果 condition 为真(true),则执行 then-body,否则执行 else-body。
    $ ~3 B* P' q# b5 @& c举一个例子如下:
    8 Y0 r& G( |1 w! Uif (x % 2 == 0)3 a: ]6 C% P$ e( {  i) ?  K
    print "x is even"
    6 y. L& Z- Q, V" y! h$ Felse
    1 z  n1 _" D6 ]  Aprint "x is odd"$ P6 }7 _& v7 i; W2 ?

    " D# Q. i! U9 }3 _7.2 while 叙述
    # ~1 U( Y/ ]! y/ y' @1 b8 awhile (condition)
    ' Y; A' u1 _! B; x- R4 q! f7 b% [6 e7 Hbody, f% V$ J" f" l
    while 叙述做的第一件事就是测试 condition。假如 condition 为真则
    ; {4 u' P. @" M: }: ?6 @执行 body 的叙述。body 的叙述执行完後,会再测试 condition,假如
    ! [+ j8 `6 n' }0 ?condition 为真,则 body 会再度被执行。这个过程会一直被重复直到
    & s1 M( e: @; K, K5 fcondition 不再是真。如果 condition 第一次测试就是伪(false),则0 a% V2 n0 Q) A) o
    body 从没有被执行。) u2 S: p- V. J. y, S& H
    下面的例子会印出每个输入记录(record)的前三个栏位。3 D: @4 u; a9 N# f
    gawk '{ i=1- a2 V9 k# u1 r! }+ ~
    while (i <= 3) {" W* A' ]6 @- J5 Z* |
    print $i) `# X3 G& J  S3 h9 {5 Q1 [
    i++
    ! e9 Z! `3 o" \  J) y' @6 w1 }}
    8 C" [; u/ A' `5 P4 d4 H4 H2 t}'  _4 `8 @0 B! r; P. v% T
    $ B4 z5 e5 e' b6 t
    7.3 do-while 叙述
    / j% v% Z7 t/ {+ {$ P; Qdo
    $ C4 [* w1 R" o! ~# n0 \4 m/ Pbody# ^6 p5 S7 a9 \, B0 e2 h
    while (condition)- [& M9 R3 i+ j
    这个 do loop 执行 body 一次,然後只要 condition 是真则会重复执行 body。5 A9 H! g! ]& ^" W
    即使开始时 condition 是伪,body 也会被执行一次。5 Y! w  \# j7 n. @6 m1 N* n
    下面的例子会印出每个输入记录十次。
    # L- B% d. H9 [/ ugawk '{ i= 1. e5 T7 H8 l% V8 G$ v, A9 ?
    do {
    1 d: I* x# l% kprint $01 R, X2 f1 C+ \, I
    i++
    1 h& s7 D" ^  a} while (i <= 10)
      ~6 K* v6 {4 o}'
    * [2 @- j  D1 ], U" M& I2 q/ x
    , V% @5 t% {8 _0 E: x: H7.4 for 叙述5 H8 w8 }6 n. ^, D, c5 }7 u) C
    for (initialization; condition; increment)1 s1 \$ D2 _+ x2 E. @5 `! o
    body
    # o- H, c! K+ y3 [. a此叙述开始时会执行initialization,然後只要 condition是真,它! T  U: V7 D3 ^3 b
    会重复执行body与做increment 。
    ) C, [" W) P2 ~5 s$ K. X下面的例子会印出每个输入记录的前三个栏位。2 c) u% P+ _& W- X  z7 `
    gawk '{ for (i=1; i<=3; i++)
    / ~& N! I# y; E. zprint $i
    9 h$ u7 b; e5 r# h}'
    2 y9 v2 X5 a# g& ^
    7 z1 l& m% K6 g7 I' ^" A7.5 break 叙述+ }( ?/ K: z8 Q+ D: O
    break 叙述会跳出包含它的 for、while、do-while 回圈的最内层。
    2 D8 b/ L% i0 _4 F9 r+ Q下面的例子会找出任何整数的最小除数,它也会判断是否为质数。5 Y3 d6 @( C" I& y+ F0 F7 n. y
    gawk '# find smallest divisor of num
    $ ^% f+ A3 [: X# S{ num=$1
    & P7 h0 J5 g( C" ^( ]for (div=2; div*div <=num; div++)) s. L) p( ~) V; O8 n" B- n# H" l2 `
    if (num % div == 0)
    4 V" f5 y. X! K* K% [break6 Z5 G* f0 l8 e' R% ?# p
    if (num % div == 0)
    , \$ P  N4 l1 q5 j9 zprintf "Smallest divisor of %d is %d\n", num, div
    8 ?4 Q( Q9 R' x; I+ B8 C  E. kelse
    * v5 P: G. P# Lprintf "%d is prime\n", num }'9 d/ S0 ?" b' L. P8 u. B4 I
    % V' D* A1 f& X5 k& s( q% k
    7.6 continue 叙述2 w2 j# a" t9 {
    continue 叙述使用於 for、while、do-while 回圈内部,它会跳" K2 V% L! b7 t2 x$ B
    过回圈 body 的剩馀部分,使得它立刻进行下一次回圈的执行。; I5 H5 y  T! X! i: S. w
    下面的例子会印出 0 至 20 的全部数字,但是 5 并不会被印出。
    " S8 f; n; a$ r! [gawk 'BEGIN {' g! V& E# c% E! Y8 b
    for (x=0; x<=20; x++) {/ p" H" u1 x" ~% W! Q; R5 M
    if (x==5)
    : [( f3 Z; U4 L; H. J: ^4 }continue  _$ n. H4 r1 [2 U0 G, }
    printf ("%d",x)2 a1 s& \& U5 d. @9 Y2 K1 k2 W
    }
    0 m6 J! E# A5 {9 L- O% {. tprint ""; T  ~( }% r0 n- O
    }'3 F. ]# ]! W5 R5 d

    0 j9 G5 G- ^- B7.7 next 叙述、next file 叙述、exit 叙述  |' i  K! e9 H4 {8 S" l1 j
    next 叙述强迫 gawk 立刻停止处理目前的记录(record)而继续下一% D( ^8 S9 U6 s/ F) C) K
    个记录。0 p8 n7 `1 v4 R+ g: {
    next file 叙述类似 next。然而,它强迫 gawk 立刻停止处理目前
    . h1 G" n1 V( `( B的资料档。8 i% D4 b2 _. o# b
    exit 叙述会使得 gawk 程式停止执行而跳出。然而,如果 END 出现
    - w+ v# n* W: }+ w,它会去执行 END 的 actions。5 P* B. l; ?' ~2 ]/ S. o+ R3 G

      I9 L+ O- {1 o" ^+ B第八章 内建函式(Built-in Functions)$ w3 [* i  G' Z. S
    内建函式是 gawk 内建的函式,可在 gawk 程式的任何地方呼叫内建
    # R( i" I2 ], {函式。
    3 a5 m' x3 i5 O; P$ Q0 ^, F) n$ h& g7 N
    8.1 数值方面的内建函式
    : ]- [2 O0 K9 K" Bint(x) 求出 x 的整数部份,朝向 0 的方向做舍去。例如:int(3.9)
    ! @; X+ D4 r7 J, z7 Z. Y1 U$ q! T8 H; v是 3,int(-3.9) 是 -3。
    1 z9 ?) G7 M. J  [  t1 d  U/ Jsqrt(x) 求出 x 正的平方根值。例 sqrt(4)=29 z% S/ m8 Y2 M3 V2 e, W
    exp(x) 求出 x 的次方。例 exp(2) 即是求 e*e 。5 D/ b1 w& B& ^4 \2 P
    log(x) 求出 x 的自然对数。: |) \" d7 y0 F& X2 |! n2 \
    sin(x) 求出 x 的 sine 值,x 是弪度量。$ [" T' V- g" \) f7 e1 c
    cos(x) 求出 x 的 cosine 值,x 是弪度量。; z# u4 P# l8 I' h/ T  @! R
    atan2(y,x) 求 y/x 的 arctangent 值,所求出的值其单位是弪度量。
    - r: n! H) I+ B) U; }5 s) Krand() 得出一个乱数值。此乱数值平均分布在 0 和 1 之间。这个
    4 D  a$ t& N, q# Y3 R值不会是 0,也不会是 1。
    - r4 C9 v1 `+ Z( L! X, ]每次执行 gawk,rand 开始产生数字从相同点或 seed。
    - `# `5 }" U- G' o" n4 P) Osrand(x) 设定产生乱数的开始点或 seed 为 x。如果在第二次你设5 q! d! Q/ k  P7 f# b
    定相同的 seed 值,你将再度得到相同序列的乱数值。
    ) P! M8 b+ H- F) I7 @5 J如果省略引数 x,例如 srand(),则现在的日期、时间会
    1 d/ x5 g/ ?5 }! V9 ~被当成 seed。这个方法可使得乱数值是真正不可预测的。. s' _* H+ ?/ J, z
    srand 的传回值(return value)是前次所设定的 seed 值。
      z. n& [9 y% b$ T2 B# J6 A* L0 P
    ! r7 s4 E- a& ], U8.2 字串方面的内建函式3 D4 ~, H/ m% t4 h! t/ N* c' w
    index(in, find)
    * v4 y# \. U+ f! R* g它会在字串 in 里面,寻找字串 find 第一次出现的地方,传回值是
    4 j) x; r5 p& m9 s字串 find 出现在字串 in 里面的位置。如果在字串 in 里面找不到字
    % \1 t7 o% D# ^  I" `6 P3 I串 find,则传回值为 0。& m0 [4 c6 C, g9 D. _, d
    例如:
    6 l3 D# e  p- ~6 ]" k7 {print index("peanut","an")
    - i. [' U! A1 m  J0 {会印出 3。3 |- R: @  V+ \- I; N
    length(string); m& g9 M$ H4 ?% T9 M5 C1 x0 z
    求出 string 有几个字元。
    3 Q9 D7 u4 S- k4 h' O例如:" y$ o  B9 k6 b
    length("abcde")
    & o0 g4 u% u2 I是 5。
    & k" p$ I' ^4 H/ i7 x$ r, Omatch(string,regexp)
    ! M2 V/ ~- C$ H" _# A0 K8 Omatch 函式会在字串 string 里面,寻找符合 regexp 的最长、最靠
    3 q8 S/ Z, `  f' z: d: {& o左边的子字串。传回值是 regexp 在 string 的开始位置,即 index$ q1 n$ g' W) d2 z& c. X. V
    值。
      W+ X4 o# |+ \; W: ], `, @" Fmatch 函式会设定内在变数 RSTART 等於 index,它也会设定内在变
    , \" {: q0 [6 l  }+ d" D' @2 K" r5 d数 RLENGTH 等於符合的字元个数。如果不符合,则会设定 RSTART 为4 a. M) h% X& x' Y; t$ t2 ^$ b
    0、RLENGTH 为 -1。
    9 g) s9 R! d& l7 [- g6 Rsprintf(format,expression1,...)
    4 w$ m" C" U* B8 ^% n3 x2 N8 _举 printf 类似,但是 sprintf 并不印出,而是传回字串。; [% P8 P0 j8 a9 @" B$ P
    例如:* X& C; T: t/ W; e
    sprintf("pi = %.2f (approx.)',22/7)
    7 v1 z' s9 [) {% H$ R4 m8 p传回的字串为"pi = 3.14 (approx.)"
    5 p* s& ]7 o* I2 t  b9 \sub(regexp, replacement,target)4 ]/ Q1 R0 b9 k
    在字串 target 里面,寻找符合 regexp 的最长、最靠左边的地方,
    # k  O; ~! f( a! b' t以字串 replacement 代替最左边的 regexp。
    9 l5 r5 |6 O. J1 n0 y/ D例如:/ Y. z; W+ U# o
    str = "water, water, everywhere"7 k, a# B' e$ T# m% v
    sub(/at/, "ith",str)
    # D" R5 d% l- ~- ~, M4 `结果字串str会变成/ j$ C( @. F, P( ]# [2 v* E
    "wither, water, everywhere"
    - M. Y: }6 V* i. p5 [, {5 v9 \gsub(regexp, replacement, target)
    " G9 ~+ I$ J4 @6 F2 Fgsub 与前面的 sub 类似。在字串 target 里面,寻找符合 regexp 的
    . Y& a8 d# w* u所有地方,以字串 replacement 代替所有的 regexp。& h. v4 O! j1 l# h
    例如:
    2 C  b9 L' Z- [7 qstr="water, water, everywhere"
    3 n* i. U& `  ]gsub(/at/, "ith",str)
    * l4 N5 m6 S3 q: J结果字串str会变成
    - }' X+ U' B4 X$ v0 c0 t$ \8 t3 x'wither, wither, everywhere"
    % H0 c) M8 x% R' [: b, i0 {7 d) nsubstr(string, start, length)
    9 x) V. l) @! B5 ]* ^, K5 f传回字串 string 的子字串,这个子字串的长度为 length 个字元,
    2 d8 p1 V# s3 X! V: J. c) z. r2 t从第 start 个位置开始。
    ) T$ s4 q% c0 z5 v4 ], U6 @例如:
    3 k5 w6 @- N/ vsubstr("washington",5,3)4 @% z) ]0 J9 D$ [3 L
    传回值为"ing"3 S8 T/ ]& M" @1 ^
    如果 length 没有出现,则传回的子字串是从第 start 个位置开始0 |9 }6 R  n' X' x8 r$ E& n
    至结束。+ G1 a/ {& S9 w3 c/ N( J% e' e/ z
    例如:
    ! J1 o& x0 B/ _' [7 v$ A. {substr("washington",5)
    & b- r, V$ R  e- I6 X传回值为"ington"
    ! E; k+ f2 ^& b: htolower(string)
    ! U" {9 t7 S. E7 \将字串string的大写字母改为小写字母。
    % T. H6 n: k6 m9 O6 P例如:- _5 K7 R& r4 q6 b
    tolower("MiXeD cAsE 123")6 A, B7 J- Q$ @% L3 _- G/ W9 j7 Q% I
    传回值为"mixed case 123"
    3 B# P6 _& \: Q7 Z3 wtoupper(string)0 i8 N; F' T7 @! B0 f( a$ c% h
    将字串string的小写字母改为大写字母。
    - ?: E+ p! C$ S4 a例如:
    1 L0 G# L/ g, {) \toupper("MiXeD cAsE 123")/ u, Q& |9 n% m1 d' |
    传回值为"MIXED CASE 123"
    % h# k; D7 d3 S+ l6 C" k7 S3 B' M( E; ^  N# B8 j* I' I
    8.3 输入输出的内建函式
    7 `* Z  l; w+ mclose(filename)
    ( `8 G) i* ]. I) l$ M9 l" S, C# M将输入或输出的档案 filename 关闭。8 j7 w* W3 @7 ]0 z, W
    system(command)
    $ q: O; X# d3 |) z' B4 a2 a( D此函式允许使用者执行作业系统的指令,执行完毕後将回到 gawk' ?  C' K6 _+ s1 o0 N
    程式。
    ) Q% y' v3 a% p' S3 q) N例如:
    ; K1 `: ]' F1 o+ l4 j1 p4 iBEGIN {system("ls")}! d2 u5 T- M% j6 Z# c

    6 s% \4 V" _1 x第九章 使用者定义的函式(User-defined Functions)3 B+ k6 ]- j9 I' w( j( ?7 ]
    复杂的 gawk 程式常常可以使用自己定义的函式来简化。呼叫使用! Y- ?  D+ b" k$ \
    者定义的函式与呼叫内建函式的方法一样。1 h: B" d! N+ m7 U2 C: b, G
    3 q% f" b' a' b
    9.1 函式定义的格式( c! U3 m, i5 k
    函式的定义可以放在 gawk 程式的任何地方。, R5 O" n( T% ]( t- \' f6 u0 W
    一个使用者定义的函式其格式如下:* K0 g* d' N% S2 A) v
    function name (parameter-list) {" a& I" b, |! \# r
    body-of-function, N# D  H% ?# U+ r0 K: h' v  p. p7 a
    }; O( _- ]: L5 g- \) j" Y
    name 是所定义的函式之名称。一个正确的函式名称可包括一序列的字
    % K" |5 b6 e) _' v4 D母、数字、下标线 (underscores),但是不可用数字做开头。
    4 J8 T/ k. G1 i# u8 Aparameter-list 是列出函式的全部引数(argument),各个引数之
    1 R% W! Q6 C- E4 P间以逗点隔开。
    4 q% C+ u$ z, b* S9 ibody-of-function 包含 gawk 的叙述 (statement)。它是函式定义8 `& r% V. s! ^3 G- G5 ]9 `# o8 i
    里最重要的部份,它决定函式实际要做何种事。$ `/ S, v9 t! K' n+ ?0 K
    : H) y  T% Z% G; d  ^0 \( H; J
    9.2 函式定义的例子
    3 N4 C) V' a' Y; @1 [" r下面这个例子,会将每个记录的第一个栏位之值的平方与第二个- {8 r) y6 r' A0 t+ T
    栏位之值的平方加起来。* @3 m* q; K/ l; ~' i
    {print "sum =",SquareSum($1,$2)}/ I# O5 V% X  ?0 K9 x2 u1 D
    function SquareSum(x,y) {
    0 L. |. Q; ^! L, Jsum=x*x+y*y# W4 o% C$ e! e
    return sum7 b( i$ j  Z2 S  @/ L
    }( C: O: [; S# s6 S  L& H* V' P4 v  Z
    / j3 s. z2 i( N- z. @
    第十章 □例
    , Q' H) [8 [2 y# B5 }) R" Z- D这里将列出 gawk 程式的一些例子。
    3 f4 |9 h' b% V0 i. ?# Ggawk '{if (NF > max) max = NF}( I9 G8 P! A3 ~! M: H5 M4 C; I# C
    END {print max}'- y- x& Q& }- B
    此程式会印出所有输入行之中,栏位的最大个数。. v$ G/ _7 p  |5 [. u$ b
    gawk 'length($0) > 80'( D3 @( Q. \1 O  q4 \& a6 d  g
    此程式会印出一行超过 80 个字元的每一行。此处只有 pattern 被# y3 P& }  U* O0 b! v7 A, `7 n2 }7 s3 O
    列出,action 是采用内定的 print。
    4 S+ {+ C. {/ B" H( n9 y# j4 Z, |9 xgawk 'NF > 0'3 a. m' g: A. ^" k* g. i- y! D
    对於拥有至少一个栏位的所有行,此程式皆会印出。这是一个简
    0 c/ @' [8 G8 x1 q单的方法,将一个档案里的所有空白行删除。
    9 H4 p9 n/ O/ Y7 [: A2 }" Tgawk '{if (NF > 0) print}'
    5 m7 _) Y& I3 ]7 ^2 C9 f& V: _/ a对於拥有至少一个栏位的所有行,此程式皆会印出。这是一个简
    : l; U! ]. i9 w+ d4 b, l) e单的方法,将一个档案里的所有空白行删除。/ G6 t/ U  l9 j8 y
    gawk 'BEGIN {for (i = 1; i <= 7; i++): q, `2 A0 v3 b
    print int(101 * rand())}'
    + T! u1 o8 j  {( K- {! P: G7 T此程式会印出□围是 0 到 100 之间的 7 个乱数值。
    # }+ ]) i. ^% g3 V/ [$ Dls -l files | gawk '{x += $4}; END {print "total bytes: " x}'
    3 E$ O: N9 x: O# V# V1 N  `此程式会印出所有指定的档案之bytes数目的总和。
    , K7 H2 D7 E% d1 C5 r7 j  O3 [expand file | gawk '{if (x < length()) x = length()}
    & c6 H1 p/ }2 i+ h/ \END {print "maximum line length is " x}'/ H1 d6 G) O1 ?' P/ Q6 a$ R
    此程式会将指定档案里最长一行的长度印出。expand 会将 tab 改
    7 j: {" Y( a& l5 q成 space,所以是用实际的右边界来做长度的比较。
    / G, A9 U& z/ h$ S! xgawk 'BEGIN {FS = ":"}
    9 w5 F1 p6 X8 G- w$ e  Z{print $1 | "sort"}' /etc/passwd" o' i2 X" z9 c5 S( }5 R
    此程式会将所有使用者的login名称,依照字母的顺序印出。
    8 ]- e. |* U3 x0 Kgawk '{nlines++}
    ' M5 j3 S& {3 p' {. [+ a! lEND {print nlines}'4 z) ^% x$ m  e7 o, D
    此程式会将一个档案的总行数印出。
    0 w8 D# z( Q6 z; W7 Wgawk 'END {print NR}'
    " N& b' H5 {; A此程式也会将一个档案的总行数印出,但是计算行数的工作由gawk
    ) @0 h+ H4 Z$ I# r6 ?. `! ?来做。# B8 }; b+ I* d0 @7 X
    gawk '{print NR,$0}'
    ; P' |& J& ]4 x6 ]# C此程式印出档案的内容时,会在每行的最前面印出行号,它的功8 n  d2 \5 G$ H8 @7 E: W: P
    能与 'cat -n' 类似。, z* b: c8 ?0 C# @3 O6 v
    6 k" B1 Z# j0 |8 B
    第十一章 结论; Y5 G+ G5 n; U* D3 r! T% S% q. O
    gawk 对於资料的处理具有很强的功能。它能够以很短的程式完成
    # ?4 W" \1 a: h: F1 e想要做的事,甚至一或二行的程式就能完成指定的工作。同样的一件  b8 G9 \; ~( E$ I  d
    工作,以 gawk 程式来写会比用其它程式语言来写短很多。, ^' S7 s4 U$ F1 c
    gawk 是 GNU 所做的 awk,它是公众软体(Public Domain) 可免费使& H. x! D' z+ v. e  m
    用。
    "真诚赞赏,手留余香"
    还没有人打赏,支持一下
    楼主热帖

    相关帖子

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

    该用户从未签到

    尚未签到

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

    本版积分规则

    招聘斑竹

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

    GMT+8, 2026-10-31 02:20

    Powered by Discuz! X3.5 Licensed

    © 2001-2026 Discuz! Team.

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