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

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

Gawk手册

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

    连续签到: 1 天

    [LV.1]初来乍到

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

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

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

    ×
    GAWK2 c) j6 U4 C* A
    第一章 前言; _2 b9 V) r/ t. {' P, h* p; G
    第二章 简介
    9 x5 }7 s7 O* P! e0 j第三章 读取输入档案- H( b+ g( B2 W* Z
    第四章 印出+ H- N) K( i2 f8 F8 q
    第五章 Patterns) l3 B# @9 V: h6 O' \3 \: v
    第六章 算式(Expression)作为Actions的叙述4 X6 ^5 P+ ?& ?8 h0 p5 y: I- y- L
    第七章 Actions里面的控制叙述
    * q0 ^8 L, d2 x第八章 内建函式(Built-in Functions)) k  Y" p6 ?2 z. V( ^7 s7 ?! B6 Q
    第九章 使用者定义的函式
    2 U& u9 M2 F4 Q/ P( [; `第十章 □例$ h9 i; |' p9 J  O6 k: @7 ]1 s* `- P) G
    第十一章 结论
    2 \, R3 e$ v  f+ ]1 p) c9 ^% X  {' ?- y
    =======================================1 e: n- }: i  v3 `% O
    第一章 前言4 J9 z& n2 K* T) {7 c' y
    awk 是一个程式语言,对於资料的处理具有很强的功能。对於文# k( f. p% u& O# L% [
    字档里的资料做修改、比对、抽取等的处理,awk 能够以很短的程式
    " b9 |5 A* B+ Y5 t* Z' _* e5 W轻易地完成。如果使用 C 或 Pascal 等语言写程式完成上述的动作,* j$ q6 w8 z0 Y, U+ S& P
    会不方便且很花费时间,所写的程式也会很大。2 @# c" }( x2 H5 j- N
    awk 能够依照使用者的定义格式来分解输入资料,也可依照使用( q2 @4 D& N8 d
    者定义的格式来印出资料。, v, Q, T  W3 \! ?
    awk 名称的由来是由它的原始设计者的姓氏之第一个字母而命名
    ' y1 Q6 ^" y0 S" D:Alfred V. Aho, Peter J. Weinberger, Brian W. Kernighan。2 y# T7 P: J" O# @4 M- \+ {) _
    awk最初在1977年完成。一个新版本的awk在1985年被发表,它的功能
    ( N$ m3 j0 M/ K7 U2 i2 A- Y- G比旧版本增强不少。
    1 V7 o* F- b5 Q+ l  d# ]gawk 是GNU所做的 awk,gawk 最初在1986年完成,之後不断地
    ; T4 d4 j7 n& R! [; p! G被改进、更新。gawk 包含 awk 的所有功能。# P$ i% w% k( V  D) Z$ C1 F+ R& z% I
    往後的 gawk 将以下面的2个输入档案来做例子说明。
    # N. V/ @# g8 L3 q9 ~6 H4 w档案'BBS-list':" I6 z/ A% f3 F6 d" }8 O. B7 k
    aardvark 555-5553 1200/300 B) w5 P1 m0 [) w2 y% n
    alpo-net 555-3412 2400/1200/300 A
    + J) ]( b7 Q1 a5 Q. b4 i4 d, Cbarfly 555-7685 1200/300 A" O* y7 e0 z* \- \
    bites 555-1675 2400/1200/300 A# C: q0 ?  ^9 g! Z' T+ x
    camelot 555-0542 300 C
    9 Z2 v, a3 c3 O4 Kcore 555-2912 1200/300 C4 I9 l. N  P9 q+ p$ k! S5 h2 l: j
    fooey 555-1234 2400/1200/300 B
    1 a2 C- e- @8 k8 X5 efoot 555-6699 1200/300 B. B; I2 ?& A9 z, A$ B% e1 t# ~& s" i
    macfoo 555-6480 1200/300 A+ v& X* T( ]5 b( u
    sdace 555-3430 2400/1200/300 A, i4 ~0 e2 v2 V- I1 X+ M
    sabafoo 555-2127 1200/300 C$ l6 S1 K7 P' z
    档案'shipped':; _% D4 @4 Z/ d) ?8 @- p
    Jan 13 25 15 115
    % p; x" J7 Y, j5 nFeb 15 32 24 226) Q( Y  c, C8 y( x' U2 p
    Mar 15 24 34 228
    ' ]5 M# M! P) R# D' s4 z. tApr 31 52 63 420+ o, q8 c5 g5 B) U! i2 ~
    May 16 34 29 208
    1 }3 V, a2 [' G& X6 R- EJun 31 42 75 492
    , K  w5 Y/ f' YJul 24 34 67 4361 w; Z6 l* O8 L: |
    Aug 15 34 47 3167 c1 ]! a2 w, r0 |9 i
    Sep 13 55 37 277+ z2 B3 d8 _+ z  ]; |' b
    Oct 29 54 68 525
      U( L5 C2 x0 i+ q  N2 p! BNov 20 87 82 577
    4 l: X. R! ]- V2 u8 R0 xDec 17 35 61 401
    9 k; T7 i2 i( G2 [* uJan 21 36 64 620
      O* r6 j) e' A0 @$ |1 BFeb 26 58 80 652& s! S* l3 ^5 N6 i
    Mar 24 75 70 495
    ' g# X2 B8 X+ CApr 21 70 74 514
    ' d0 ]! ^* C" z
    ; z9 P2 ?  q! n- m9 G第二章 简介
    & t4 _* `8 ?) K4 K7 i* W8 `9 lgawk 的主要功能是针对档案的每一行(line)搜寻指定的 patterns: I9 `- I, T+ x2 O6 D8 m! J9 K
    。当一行里有符合指定的 patterns,gawk 就会在此一行执行被指定
    / j5 w5 _9 H+ @4 f$ O3 O" a; x的 actions。 gawk 依此方式处理输入档案的每一行直到输入档案结
    4 Q2 ^7 r7 Q  f! `: t$ i4 `束。* m5 _4 R! C* z- N  t- `
    gawk 程式是由很多的 pattern 与 action 所组成,action 写在* R  Y# d% i, }/ B, g7 U# v  u
    大括号 { } 里面,一个pattern後面就跟著一个action。整个 gawk 程# F, h% T, j) s+ X& z
    式会像下面的样子:
    , f; Y. C& n$ \3 I: ^/ k; apattern {action}
    3 L' t5 V. P# p( G' M* `$ \+ dpattern {action}. E0 V8 \5 p- z# n1 p* I6 n$ H
    在 gawk 程式里面的规则,pattern 或 action 能够被省略,但7 N. A' I8 a3 b3 d. k# L2 J- D; F: f3 T
    是两个不能同时被省略。如果 pattern 被省略,对於输入档里面的
    ' F) b2 j. {+ ]8 S每一行,action 都会被执行。如果 action 被省略,内定的 action9 {: D' B6 t' A! C
    则会印出所有符合 pattern 的输入行。% O1 F7 a# B7 ^# v, [$ }( o0 b+ @

    7 h. M4 W2 {. i  ~" [0 v- |2.1 如何执行gawk程式
    0 s1 b, @6 A) T7 r9 m5 p; `基本上,有2个方法可以执行gawk程式。0 Z/ p- j' e3 w/ O2 `! M
    □如果 gawk 程式很短,则 gawk 可以直接写在 command line,如下所示:
    1 W9 }5 g5 j8 N9 r6 bgawk 'program' input-file1 input-file2 ...
    6 |7 n5 B$ E- Y3 e( [其中 program 包括一些 pattern 和 action。2 W) {  U5 ~$ N, u  f0 y  d
    □如果 gawk 程式较长,较为方便的做法是将 gawk 程式存在一个档案,
    2 H* }2 k6 I1 i即 patterns 与 actions 写在档名为 program-file 的档案里面,执行: X. c; c- `5 j" A3 |
    gawk 的格式如下所示:
    5 s* g# e1 I' u  H" rgawk -f program-file input-file1 input-file2 .... b# e& N' }, D: R  \# ~+ P- {* [
    gawk 程式的档案不止一个时,执行gawk 的格式如下所示:
    2 w2 ?/ l; @0 R5 Z/ |7 m  wgawk -f program-file1 -f program-file2 ... input-file1
    # K5 j1 d2 k- l4 Qinput-file2 ...% Y6 m) v7 N3 I; S0 ^% e

      p( a! A7 ]4 C2.2 一个简单的例子
    " I7 {" C1 }& E. Z' U: F现在我们举一个简单的例子,因为 gawk 程式很短,所以将 gawk 程
    ( X) G; k* Y  l3 e4 _式直接写在 command line。
    ' I7 z9 p) v& ]& G/ N/ A! Ggawk '/foo/ {print $0}' BBS-list
    # h' w6 e7 Y* s% r9 D实际的 gawk 程式为 /foo/ {print $0}。/foo/ 为 pattern,意思为搜
    ' y/ j1 d. U' V+ C$ T寻输入档里的每一行是否含有子字串 'foo',如果含有 'foo' 则执行 action。
    , E4 V- {+ V6 n" G/ maction 为 print $0,是将现在这一行的内容印出。BBS-list 是输入的档案。
    " D+ [; ~3 _. F2 y1 K& o执行完上述指令後,会印出下面的结果:
    " f* c" w3 d  Ffooey 555-1234 2400/1200/300 B
    * O+ t8 p3 E! h  _3 yfoot 555-6699 1200/300 B0 u. t$ x, J0 M, v. ^' r  f
    macfoo 555-6480 1200/300 A
    5 J$ \% |4 K. S9 {0 Q% M' lsabafoo 555-2127 1200/300 C
    / w& w) f& L) r: @
    & O) p! a$ X$ Z2 h5 D5 ^2.3 一个较复杂的例子" e2 @; x1 g* E8 T% T- \
    gawk '$1 == "Feb" {sum=$2+$3} END {print sum}' shipped
    ( {1 Q7 C3 d4 r2 k' G# p现在这个例子会将输入档 'shipped' 的第一个栏位与 "Feb" 做比较1 @% B* H0 l% m  Z' u
    ,如果相等,则其对应的第2栏位与第3栏位的值会被加到变数 sum。2 R+ {. f$ f7 A* `
    对於输入档的每一行重复上述的动作,直到输入档的每一行都被处理" M+ {% A' T( Y& r! d2 O6 ]
    过为止。最後将 sum 的值印出。END {print sum} 的意思为在所有的输
    4 L: l! Q4 a( V. q# a9 \# p入读完之後,执行一次 print sum 的动作,也就是把 sum 的值印出。
    % y, q! ~$ ^! L! F下面是执行的结果:& N' A* R4 t: Y: a9 E" Y
    84
    * \7 f. H" H/ T5 E" j$ O4 O  I! I, ^# W2 ]' c
    第三章 读取输入档案
    . h1 ^! g% U* X" mgawk的输入可以从标准输入或指定的档案里读取。输入的读取单/ H( ~2 Z5 y; C
    位被称为”记录”(records),gawk 在做处理时,是一个记录一个记2 l2 Y& L+ H3 _! I* F2 I
    录地处理。每个记录的内定值是一行(line),一个记录又被分为多个) O3 D7 x: ^+ x4 m; V9 a8 {! S+ t; ^
    栏位(fields)。
    : n7 q& c; B1 x1 w* z: |' ?5 V3 z% E
    3.1 如何将输入分解成记录(records)0 T/ U  t# N" M
    gawk 语言会把输入分解成记录(record)。记录与记录之间是以
    ( ?( _, ]# V# H) Srecord separator 隔开,record separator 的内定值是表示新一行的* e, t  H: w  c
    字元(newline character),因此内定的 record separator 使得文字
    + M1 W1 o% C9 ?1 p的每一行是一个记录。; E" n8 ^9 |0 H, F
    record separator 随著内建变数 RS 的改变而改变。RS 是一个字串,+ q  U/ ]6 B6 u% F1 t
    它的内定值是"\n"。仅有 RS 的第一个字元是有效的,它被当作 record
    ( H2 `5 T. Z! i0 l) {+ o' a6 Q& p0 [separator,而 RS 的其它字元会被忽略。/ A+ ~* {6 T1 @- r3 W' M) u; F" l
    内建变数 FNR 会储存目前的输入档案已经被读取的记录之个数。内
    8 J0 C3 Q- C5 g3 i9 d建变数 NR 会储存目前为止所有的输入档案已经被读取的记录之个数。
    0 ?& }8 A  W  j2 j) J( |7 G0 d* W6 W( v/ v) i
    3.2 栏位(field)9 p& G. k9 I9 Q
    gawk 会自动将每个记录分解成多个栏位 (field)。类似於字在一2 q& G5 z3 p8 w# x: S' {! N& X- L
    行里面,gawk 的内定动作会认为栏位之间是以 whitespace 分开。在; o6 z, j+ k5 W  W( z+ s5 Z9 x9 T  C
    gawk 里,whitespace 的意思是一个或多个空白或 tabs。! U) Y( f) W) C" b
    在 gawk 程式里面,以'$1'表示第一个栏位,'$2'表示第二个栏位" s' r& ?, y$ \1 {& `
    ,依此类推。举个例子,假设输入的一行如下所示:
    * {7 ^9 ?+ K% a% g0 ~9 v. J! [This seems like a pretty nice example.) \5 s* Y3 A' s2 L% D. }3 \. e3 G
    第一个栏位或 $1 是'This',第二个栏位或 $2 是 'seems',依此类推。' J9 }- s. F* W% w$ R6 ?
    有个地方值得特别注意,第七个栏位或 $7 是'example.'而非'example'。
    . ?* g0 S1 ]8 |1 E不论有多少栏位,$NF 可用来表示一个记录的最後一个栏位。以; r/ E/ V4 Q$ V) y
    上面的例子为例,$NF 与 $7 相同,也就是'example.'。
    9 L9 i0 B& ^/ E* F% o: w0 o) gNF 是一个内建变数,它的值表示目前这个记录之栏位的个数。
    3 w$ u! p# M. F5 |. ~, F% X8 Y" P$0,看起来好像是第零个栏位,它是一个特例,它表示整个记录。5 p, A3 M5 O( |% v2 h2 m+ a7 E
    下面是一个较复杂的例子:# ~% c  Z5 g3 b+ y% s2 C
    gawk '$1~/foo/ {print $0}' BBS-list. e4 r( ^1 V0 |5 [$ j  s7 [: x
    结果如下:7 E( z0 w3 v$ |1 [8 c- I) N5 n* H  I
    fooey 555-1234 2400/1200/300 B$ Y4 d' b% J: g4 H; s
    foot 555-6699 1200/300 B0 K/ ?2 V- v8 l  N3 j' n2 u
    macfoo 555-6480 1200/300 A% f# C, Y. }; R& v! [
    sabafoo 555-2127 1200/300 C+ j0 ]" [% U7 P& t
    这个例子是把输入档'BBS-list'的每个记录的第一个栏位作检查,如
    4 ]. `' A3 W& i5 t0 c果它含有子字串'foo',则这一个记录会被印出。
    " I9 W; s1 G9 B: J0 ~, N' p9 ~5 z3 c
    # y8 I$ d7 _5 p8 z) C; n0 D0 Z3.3 如何将记录分解成栏位4 }3 [- k' g8 y& Z9 |
    gawk 根据 field separator 将一个记录分解成栏位。field sepa-* P5 E5 ~6 M( ]
    rator 以内建变数 FS 表示。
    5 k' m5 `* [+ }' l举个例子,假如 field separator 是'oo',则下面的行:
    . T- a3 @- _6 ^moo goo gai pan
    + j0 T& g) r. G' H6 l会被分成三个栏位:'m'、' g'、' gai pan'。
      I% i  b: D& }- @在 gawk 程式里,可以使用'='来改变 FS 的值。例如:
    1 _9 m' k4 v% }+ l4 h$ \0 egawk 'BEGIN {FS=","}; {print $2}'
    & p3 Z& y# p5 G7 p, a) V+ p, a输入行如下:
    7 g) o. b! \5 h& @& O, RJohn Q. Smith, 29 Oak St., Walamazoo, MI 421395 L2 ~3 J! e& g' A) h7 v
    执行gawk的结果将印出字串 ' 29 Oak St.'。BEGIN 後面的 action 会在
    0 |5 H3 R4 u: ~. H/ A& K/ a第一个记录被读取之前执行一次。
    % S2 |" w4 ?& f1 H! Q
    ( t% ~- L% f9 w, w' H8 }8 I第四章 印出
    % B7 j4 N6 w. ^/ A' z/ x在gawk程式里,actions 最常做的事就是印出(printing)。简单
    6 f  J7 z2 i$ w6 Q& ?的印出,使用 printe叙述。复杂格式的印出,使用 printf 叙述。" O, p- N& ~& e& e

    * V7 U5 G  e9 S9 ]$ I( p6 T: Z4.1 print叙述  j" m: \5 N! ]1 a3 i
    print 叙述用在简单、标准的输出格式。叙述的格式如下所示:9 z7 Q7 K* q5 d1 K1 r  S
    print item1, item2, ...
    3 B$ T- h6 j* Z+ D: [0 g/ L7 s输出时,各个 item 之间会以一个空白分开,最後会换行(newline)。0 P- ]8 R9 b* d, Y; N# `; F% F% U& I
    如果 'print'叙述之後没有跟著任何东西,它与'print $0'的效
    # f  w. g4 c# R, v# r2 ^# e果一样,它会印出现在的记录(record)。要印出空白行可使用'print
    3 j6 m& T' D/ P% t$ V""'。 印出一段固定的文字,可用双引号将文字的两边括起来,例如
    8 u, ~3 ]6 s/ ~. }'print "Hello there"'。
      m( d! w+ Q& p; s- q; c这里是一个例子,它会把每个输入记录的前二个栏位印出:
    1 r( L6 ]$ d0 _0 E, m0 Q2 Tgawk '{print $1,$2}' shipped, f' T. S8 h- q3 _% x+ m2 K1 ]+ K
    结果如下所示:
    6 |0 Q- P& e, N( [  i! jJan 136 `, n! ?4 t* d6 W& t  r1 r6 A
    Feb 15
    5 F# }4 ^- K8 w: t1 b- N& @/ O/ JMar 15
    1 }) v! y) L$ Q; ~) E$ xApr 31
    0 _# _1 L) B6 B/ o8 _May 16
    7 v: ?# p; [2 `: P* H: D  GJun 31
    0 r5 y7 G7 ]. l- SJul 24
    9 j3 y3 q; s* x' d! a  HAug 155 o* D" Z6 |' E) f* z: o
    Sep 13
    ' Y2 L: @* ?; x, G- X" iOct 29
    5 }3 Q- k5 C) _9 w! ~; B* uNov 209 c/ _% p. n3 i, B6 D
    Dec 17
    ( `7 f0 D, P  b+ D, iJan 218 O' L2 Y( L/ d# Q* {. n: h; {2 o
    Feb 26
    5 c5 ?) ?/ ~7 x) xMar 24
    5 ]5 C! r: D! U0 |3 `Apr 21
    8 K# S8 \, _4 w! s5 F
    5 L! \' ]! d1 u7 x4.2 Output Separators! C7 S' ~) L9 d
    前面我们已提过如果 print 叙述包含有多个 item,item 之间
      }" U, d9 c  L- [  j4 h# k2 B用逗点分开,则印出时各个item会被一个空白隔开。你能够使用任何1 Z: j5 Z5 X$ B% P4 y; S. b$ i5 `
    的字串作为 output field separator,可以经由内建变数 OFS 的设8 c7 ~  \2 Z7 C) z+ ^9 A
    定来更改 output field separator。OFS 的初始值为" ",即一格的
    + `9 G: v9 p# e" h2 Z. ]空白。" N! x) Y( v5 e# V+ |
    整个 print 叙述的输出被称为 output record。print 叙述输
    1 e3 `* V7 [# g+ \% b出 output record 之後,会接著输出一个字串,此字串称为 output
    : U& c, W2 s& l$ Krecord separator。内建变数 ORS 用来指明此字串。ORS 的初始值
    ( V! ?/ |) E- m$ }* M# J( C; ~为 "\n",也就是换行。
    9 z" \' h+ t( u下面这个例子会印出每个记录的第一个栏位和第二个栏位,此二6 B" O. u- K( W1 O  ^8 s
    个栏位之间以分号';'分开,每行输出之後会加入一个空白行。" M6 y* \! e9 F
    gawk 'BEGIN {OFS=";"; ORS="\n\n"} {print $1, $2}' BBS-list- ^+ E# P7 Q5 P) U$ H/ ~4 z9 k
    结果如下所示:
    ' N8 Z5 n/ S7 d3 A) j; Waardvark;555-55530 `0 y( g% J% B2 r+ B
    alpo-net;555-34128 p: W: R" X: L
    barfly;555-76856 O0 O9 \( D7 Z0 y
    bites;555-1675
    5 U0 a! |2 `" J0 U/ t; Wcamelot;555-0542
    * _+ o# j' j* icore;555-29120 Z4 P! E$ p  Y: N- b
    fooey;555-1234$ q# k' U& X# `% b2 `. Y( Q3 {( S
    foot;555-6699
    4 Y! F7 S3 {/ [2 U. R7 w* Emacfoo;555-6480
    4 }: \/ E' Q3 w$ O0 T) `) gsdace;555-3430
    ! N3 D# U; u  ?sabafoo;555-21271 e; p8 L8 h2 Y& x1 D- C' Q

    8 W  ?6 @& j" e9 h0 W& V$ y4.3 printf叙述
    5 B: k8 ^. q! h: ?: Pprintf 叙述会使得输出格式较容易精确地控制。printf 叙述可以
    8 h- e7 v- O1 ^+ Z: w指定每个 item 印出的宽度,也可以指定数字的各种型式。
    1 h* b+ |! `1 b0 V- R" nprintf 叙述的格式如下:
    3 q) J6 U% ^$ ~2 j" Qprintf format, item1, item2, ...
    ; d# n3 Q  Y# Z5 Fprint 与 printf 的差别是在於 format, printf 的引数比 print
    9 D% V9 \- l+ q& U多了字串 format。format 的型式与 ANSI C 的 printf 之格式相同。
    % o3 _+ E% O2 s3 @6 oprintf 并不会做自动换行的动作。内建变数 OFS 与 ORS 对 printf 叙' Y8 d& [4 I2 S# t" M5 h
    述没有任何影响。
    , e# q2 a& T; a, s  Y% i% S0 X格式的指定以字元'%'开始,後面接著格式控制字母。7 u' N" f$ a3 u9 \- {7 x9 g7 b6 v
    格式控制字母如下所示:
    & a/ r, [* k6 ^+ v3 @5 }) I. B'c' 将数字以 ASCII 字元印出。3 e9 S' x2 k- M9 [& z
    例如'printf "%C",65'会印出字元'A'。
    + {/ L- b/ @2 E! A, P4 o'd' 印出十进位的整数。
    9 o" H, E+ K% y'i' 印出十进位的整数。
    - q2 r) b# @# R'e' 将数字以科学符号的形式印出。" b9 i5 s! I4 a* q& w, G
    例如; H% W; b& I$ q8 A' B4 V; [, V/ E
    print "$4.3e",19508 C' y" N8 D& _% z$ t. ~
    结果会印出'1.950e+03'。  H( U8 D1 S7 P( w$ p  z) o7 V
    'f' 将数字以浮点的形式印出。
    ) f7 K- _! t( _! a: L'g' 将数字以科学符号的形式或浮点的形式印出。数字的绝对值如果
    1 ^& W. t) x+ M4 w+ Y0 S大於等於0.0001则以浮点的形式印出,否则以科学符号的形式印
    , `" \9 w' Q5 _4 }9 c3 o' \, @$ s5 u5 V出。
    0 O; j0 v: R! e* k7 B/ I; s  i" G'o' 印出无号的八进位整数。
    5 A$ f& \2 a& i's' 印出一个字串。
    , [1 V7 D. F! t* l& \: Q'x' 印出无号的十六进位整数。10至15以'a'至'f'表示。! }% o' d( T# O# g* W4 U
    'X' 印出无号的十六进位整数。10至15以'A'至'F"表示。  K) _7 ^' t: I& O6 |6 b% ~  F* E
    '%' 它并不是真正的格式控制字母,'%%"将印出"%'。" p- H9 U0 `3 X: T) R1 ?1 d
    在 % 与格式控制字母之间可加入 modifier,modifier 是用来进一: Y6 S8 }$ H( T- J7 V- c2 {
    步控制输出的格式。可能的 modifier 如下所示:
    2 `& Y/ J8 }( {* z4 g' o9 g'-' 使用在 width 之前,指明是向左靠齐。如果'-'没有出现,则会在
    , S( h7 c' W- n3 L5 y) D0 F被指定的宽度向右靠齐。例如:, c( u" K6 R2 Y- h$ y
    printf "%-4S", "foo"
    9 M5 N+ z. b7 J/ n) g8 h) m# t会印出'foo '。: R' R0 E' D- u  `: o5 z
    'width' 这一个数字指示相对应的栏位印出时的宽度。例如:
    : |, n& y$ D. A# D4 g! y/ vprintf "%4s","foo"  G- ^6 O6 r* u2 H- C7 m4 C
    会印出' foo'。4 y  U& y; B4 b$ A! N9 K$ M
    width 的值是一个最小宽度而非最大宽度。如果一个 item 的( f, l& y: D# {& b( s* j, u, o
    值需要的宽度比 width 大,则不受 width 的影响。例如
    + |% f( v" S+ r9 d! |( }" j- m& L$ Iprintf "%4s","foobar"
    " B# D$ ~. [, P- L0 [2 m将印出'foobar'。
    ! U' a9 k% t4 `8 \! H% u$ L'.prec' 此数字指定印出时的精确度。它指定小数点右边的位数。如
    & E+ g/ l6 g+ V& \/ }1 A( N果是要印出一个字串,它指定此字串最多会被印出多少个字
    " J4 e5 ]- v$ Q; y元。8 T  U- @7 U7 X9 t. [) r( d
    8 L6 f2 x5 Z/ s( g
    第五章 patterns1 _; |- V& r& j% D
    在 gawk 程式里面,当 pattern 符合现在的输入记录(record),其1 F5 u! d2 |- R5 C: C
    相对应的 action 才会被执行。7 i" M' e& v4 ?/ \  v" y

    ( E2 Y! Q# A7 R" Y5.1 Pattern的种类
    # o! q7 o- r5 m- o/ d1 F这里对 gawk 的各种 pattern 型式作一整理:
    " X" j4 z; P1 m' @/regular expression/6 @0 p5 k; {5 \! N: Q
    一个 regular expression 当作一个 pattern。每当输入记录 (
    7 n2 D% D. S% f3 ]* Irecord)含有 regular expression 就视为符合。# a8 Y/ F7 d0 P- E5 N: @& e
    expression
    6 z/ X+ y- E* V4 r一个单一的 expression。当一个值不为 0 或一个字串不是空的," |4 G; x6 o* ]+ ~( M
    则可视为符合。( w! r, P" H. r0 f" B* j
    pat1,pat2
    0 c9 s/ e" @7 Y! L! c, V一对的 patterns 以逗号分开,指定记录的□围。! C8 }0 d9 X. O5 e+ C
    BEGIN
    / U# P6 N6 \5 j3 a( E; }3 o$ VEND, ?5 r- }9 q' ~- ~% l: S
    这是特别的 pattern, gawk 在开始执行或要结束时会分别执行相
    , L, m. c# f' A+ M$ I. B) }) Y对应於BEGIN或END的 action。! s& D1 }" s2 K5 ]/ S
    null
    $ `8 ]9 t0 q% e8 M; c2 H/ R5 p这是一个空的pattern,对於每个输入记录皆视为符合pattern。
    : {8 C, R2 Q( I7 Y  `
    # q2 u/ Z+ I' G  [5.2 Regular Expressions当作Patterns
    ; {5 ]2 t* E! x. q1 @) ]: q一个 regular expression 可简写为 regexp,是一种描述字串的方4 h" J7 I! n/ E
    法。一个 regular expression 以斜线('/')包围当作 gawk 的 pattern。
    7 m2 P* [) U& F- W$ l) G) B% j9 B如果输入记录含有 regexp 就视为符合。例如:pattern 为 /foo/,; q% ]; u9 x7 i; b+ o0 ^
    对於任何输入记录含有'foo'则视为符合。4 e5 }" l0 l0 `4 J% \! `* S6 N
    下面的例子会将含有'foo'的输入记录之第2个栏位印出。
    & E/ V. M  |9 c2 d0 P) s+ agawk '/foo/ {print $2}' BBS-list
    / g: x5 ~# V, n$ ~# [: ?3 X结果如下:3 ]; W# m6 t/ Y* H
    555-12348 F: v. U1 u, s& Q% H) H. ]
    555-6699
    3 g- I* ^! k( E5 b9 z5 J  K555-6480
    9 j. v5 B: x6 c8 ^+ |555-2127
    : v" z( k7 h' Aregexp 也能使用在比较的算式。5 |$ m! q! S6 E" x
    exp ~ /regexp/4 W0 \" Z" x& E, O2 y
    如果 exp 符合 regexp,则结果为真(true)。
    # N8 p% m. ?! f- E3 r$ zexp !~ /regexp/0 U6 k/ E5 n, {) w' X
    如果 exp 不符合 regexp,则结果为真。
    & E  z. Z$ {) z1 G. f
    & y0 i0 |1 b: _- A5.3 比较的算式当作Patterns
    ! A; F5 c  J# f% d3 t+ X0 q比较的 pattern 用来测试两个数字或字串的关系诸如大於、等於
    4 a  n' M7 b7 ]$ F5 b、小於。下面列出一些比较的pattern:
    ' I3 W4 t+ H3 O/ D9 ix<y 如果 x 小於 y,则结果为真。% }$ E; O" S6 ]+ _% c
    x<=y 如果 x 小於、等於 y,则结果为真。
    6 r; C: O1 |! j# Y+ l, gx>y 如果 x 大於 y,则结果为真。4 [! G( ^0 r% _6 G$ p
    x>=y 如果 x 大於、等於 y,则结果为真。
    1 b, T( S8 J, U, E/ e) j6 A: kx==y 如果 x 等於 y,则结果为真。
    ' n* {# M$ g6 Dx!=y 如果 x 不等於 y,则结果为真。& A: Q! j( p5 X
    x~y 如果 x 符合 regular expression y,则结果为真。+ k8 ^! B8 F/ V8 S1 `7 L
    x!~y 如果 x 不符合 regular expression y,则结果为真。
    9 O/ {4 K8 c8 Z6 M( `上面所提到的 x 与 y,如果二者皆是数字则视为数字之间的比较,5 Z# k& M6 s& ], j& e
    否则它们会被转换成字串且以字串的形式做比较。两个字串的比较,& U) i- n% A- V. a
    会先比较第一个字元,然後比较第二个字元,依此类推,直到有不同
    * t3 M( S) B$ d; N2 u" _的地方出现为止。如果两个字串在较短的一个结束之前是相等,则视+ d  W. |* Z, c( O8 `0 l2 @
    为长的字串比短的字串大。例如 "10" 比 "9" 小,"abc" 比 "abcd" 小。
    1 Y- z3 F0 P$ U) V* g0 f& e/ R# ?& N; o$ [* m
    5.4 使用布林运算的Patterns- D, j8 Y" W( d' Z6 M7 T
    一个布林(boolean) pattern 是使用布林运算"或"('||'),"及"& w1 S7 z3 C0 u3 |$ ]
    ('&&'),"反"('!')来组合其它的pattern。8 m. O5 y# h- c
    例如:" Q' D: d! r  H& ^) _4 ]# B
    gawk '/2400/ && /foo/' BBS-list! y$ I2 D( O5 H: F8 R( U" M
    gawk '/2400/ || /foo/' BBS-list7 ~+ u* B  ]% r. m- q
    gawk '! /foo/' BBS-list
    ! p" V* \1 Z7 b+ |
    / p4 V1 p8 i) _5 F第六章 算式(Expression)作为Actions的叙述% u1 k% [0 M6 ]% m+ _( _) N" M
    算式(Expression) 是gawk程式里面action的基本构成者。
    6 I& A; g( ]% M2 g" u6 n
    ' Q. O, d1 g+ P2 ^; q6.1 算术运算: [5 d  B# f4 V) @1 [7 B; E( j
    gawk 里的算术运算如下所示:- l" J$ d9 c. u1 A2 u0 Y2 J; \
    x+y 加
    6 n6 C+ T5 e0 G- Gx-y 减
    ( e1 b- z- d9 z0 ]-x 负
    5 v: x; j4 k! |2 O+x 正。实际上没有任何影响。. s* {- H* e7 C8 ^
    x*y 乘4 E1 _1 l8 S8 x
    x/y 除( ]! s# ~' W0 a) ~; l
    x%y 求馀数。例如 5%3=2。
    ) W' V$ s4 N* R# Vx^y
    ' \. E- ^$ [3 C$ n( ix**y x 的 y 次方。例如2^3=8。% ?' T/ o9 r. a8 }  H1 t0 f! {5 _

    % D7 y( V  U) A5 y6.2 比较算式与布林算式
    4 X' e3 ~! b" i" t9 k9 {/ O比较算式 (comparison expression) 用来比较字串或数字的关系
    + b% V. S) a$ d' B$ S0 V,运算符号与 C 语言相同。表列如下:
    & j2 T# |3 F7 p0 a$ mx<y7 z# v7 `0 R! b1 R. D* b
    x<=y
    # V- Q5 X" ]+ X+ i! F$ ?* v. {x>y9 s" @1 `& G( k& h! X2 m. ~9 ]
    x>=y
    & S; ?; M3 Z% ~0 {  r( [. }+ rx==y
    5 @4 Q  b: }1 \x!=y
    ) `4 [2 v9 E1 x& w1 Nx~y
    7 Y1 k$ p, i& Y6 E1 |( Zx!~y! ^- x2 H" ~% M6 c( g
    比较的结果为真(true)则其值是 1。否则其值是 0。
    " H5 U$ p! ?' {2 T* _" p布林算式(boolean expression)有下面三种:
    0 z  Z$ R: c# H, cboolean1 && boolean2
    ) G" g, g& u; g6 j6 U8 B# u$ Hboolean1 || boolean2! z1 x+ _7 ]  ?$ V5 W
    ! boolean
    . |: k# a3 j( L3 D% _* r$ K3 G3 \- b; G) x7 t
    6.3 条件算式(Conditional Expressions)& y2 M# P$ ]1 U9 `# h6 s
    一个条件式算式是一种特别的算式,它含有3个运算元。, t( e( _& S! ^% m
    条件式算式与C语言的相同:, _( v6 p+ c, J
    selector ? if-true-exp : if-false-exp# N, v) s6 `  e5 Z3 ]% ]5 c
    它有3个子算式。第一个子算式selector 首先会被计算。如果是真,/ {; S( ]5 t% B5 s9 w; t( j6 ~) U, q' L
    则if-true-exp会被计算且它的值变成整个算式的值。否则if-false-7 T/ I6 [0 a' g) P) u4 v
    exp 会被计算且它的值变成整个算式的值。3 n3 i7 X7 v! o' I$ A6 t8 N
    例如下面的例子会产生x的绝对值:
    4 Q. e9 ^- ^& {: M- W8 ^. M. D; }x>0 ? x : -x9 {* m3 O/ G; Y$ |
    ; b- l, o. U- |6 w6 v1 e1 V
    第七章 Actions里面的控制叙述
    ' {" }8 a# W& N  _- _; q在 gawk 程式里面,控制叙述诸如 if、while 等控制程式执行的流
    ! D& E( {! J" \- l, r程。在 gawk 里的控制叙述与 C 的类似。
    8 U2 P" K- }. c: h% a+ c  d5 R6 [很多的控制叙述会包括其它的叙述,被包括的叙述称为 body。假$ @- p* F) g9 e' _) u
    如 body 里面包括一个以上的叙述,必须以大括弧 { } 将这些叙述括起7 o, a8 f! S) b* D: G
    来,而各个叙述之间需以换行(newline)或分号隔开。
    # J% w/ }" V2 ?8 a2 t: \; f. h! H, @6 |, O1 y' i/ z9 _
    7.1 if 叙述
    3 _' k- P$ x& A: d1 E3 K' bif (condition) then-body [else else-body]
    4 t; i1 u9 f# p3 z: {如果 condition 为真(true),则执行 then-body,否则执行 else-body。2 g( y* z, k: {! d, ?
    举一个例子如下:( R+ C6 O! [9 i% B, h7 v7 V! S
    if (x % 2 == 0)+ x+ p2 o- g  O  {0 D, K, E
    print "x is even": ]2 b7 A( N% w' F! ?( a
    else
    2 e  b* W/ ?( @/ yprint "x is odd"
    5 @/ a* V2 o0 R9 S# u" D4 L6 ~  B6 D; J5 A
    7.2 while 叙述
      h) y7 ^4 x8 j" iwhile (condition)' a9 l" n! d0 U; S& C! k. `9 F
    body
    $ L( Z  z+ _, k$ g4 jwhile 叙述做的第一件事就是测试 condition。假如 condition 为真则0 q) ^4 ~* i3 v
    执行 body 的叙述。body 的叙述执行完後,会再测试 condition,假如2 C! ]2 k0 L: \
    condition 为真,则 body 会再度被执行。这个过程会一直被重复直到- R* ~% T, H+ `2 R# e8 x
    condition 不再是真。如果 condition 第一次测试就是伪(false),则$ S* Q' l% s$ f2 q# x
    body 从没有被执行。, v6 I: w+ x, R4 ~( J
    下面的例子会印出每个输入记录(record)的前三个栏位。
    5 W0 T' T7 `- F7 ~' [! Pgawk '{ i=1$ C( ?( v$ `' W  H. M$ j
    while (i <= 3) {
    * @( M$ ^! |2 m5 [$ @- tprint $i+ X- y! U0 }, o+ m% C) R4 f
    i++
    ! E+ h( R! z4 l) l}
    " U/ t+ w# x9 i$ Y; ^- B' t}'
    / }1 i  z4 e$ S( k, d* S+ Q6 v
    ) x) W; I$ |6 g1 |! O7.3 do-while 叙述
      i0 O  `) H+ \3 cdo/ r. E3 y: ^  S8 k: @" r
    body
    9 d& ^' [8 M" v7 a! lwhile (condition)2 q( w" ^! a+ L" g( O
    这个 do loop 执行 body 一次,然後只要 condition 是真则会重复执行 body。
    + S' Y$ s9 a3 l$ f即使开始时 condition 是伪,body 也会被执行一次。
    # S# J' e; v  J5 _1 V下面的例子会印出每个输入记录十次。' L* j: X5 B; R3 s" W
    gawk '{ i= 1
    6 o$ G4 C- X* Z  X( v- a7 bdo {4 F. [& B- n  @/ E, |- h
    print $00 m: K  c3 t, \' ^
    i++
    ! E. C" P8 \! M7 p- ]} while (i <= 10)
    1 q: U% F- A5 X' {" [, I}'
    1 k2 w9 r8 K, ^) @! T8 {# ^* l$ h
    : M' x( k9 f) F7.4 for 叙述% w0 i% W8 F  y3 Q2 n' g, O
    for (initialization; condition; increment)
    6 g% Q3 ]) B0 ]; I- [7 Q  Xbody1 t& O# ^- L4 g0 U5 W4 N8 O
    此叙述开始时会执行initialization,然後只要 condition是真,它
    / }: h5 s, ~* g8 T" u3 `会重复执行body与做increment 。
    0 x! o: r3 ~9 j8 _; l5 \  H下面的例子会印出每个输入记录的前三个栏位。
    % W; r7 e$ r* F! Z: j3 Z* ygawk '{ for (i=1; i<=3; i++)9 ?2 N. R5 |( M* g4 c; ?
    print $i
    6 o2 \  `8 c' b- h' x" G4 S) x}'
    0 }( q0 a: _- l# S- h! o+ j) d
    6 q+ u8 I+ Z8 @. O6 }% P+ z7.5 break 叙述
    & I- E3 ^1 o* ?$ [break 叙述会跳出包含它的 for、while、do-while 回圈的最内层。
    ' i5 T, r. e2 q4 G下面的例子会找出任何整数的最小除数,它也会判断是否为质数。
    - M: S+ [. d& O( j0 L7 W2 xgawk '# find smallest divisor of num
    7 A$ |7 N& F2 ^( \% Q6 X( b: x1 v{ num=$1' s2 g# t7 M6 Z* S4 G
    for (div=2; div*div <=num; div++)1 H# e" R/ o& q7 y
    if (num % div == 0)
    - a8 u# v" f8 x8 ~break/ Q1 @/ f( m! n3 u
    if (num % div == 0)9 R9 ]9 k+ q% R# {% A0 X
    printf "Smallest divisor of %d is %d\n", num, div+ a; I, u$ w- s, P7 q+ k$ P
    else9 l& |8 \9 x: I, h' K
    printf "%d is prime\n", num }'
    ) D- G$ `0 |: D$ E( V
    8 Z! S! I( X$ B8 H7.6 continue 叙述& k6 J4 y: s  q% M' f
    continue 叙述使用於 for、while、do-while 回圈内部,它会跳
    * X; `. O' i! ?6 Z过回圈 body 的剩馀部分,使得它立刻进行下一次回圈的执行。" i" T" l7 Z/ ~5 _7 \* x3 ^
    下面的例子会印出 0 至 20 的全部数字,但是 5 并不会被印出。
    - r. q, Y1 H" j8 R( ?gawk 'BEGIN {9 }% E7 m. N# @6 e& z- U
    for (x=0; x<=20; x++) {
    # M+ [: j$ {# q) h2 L3 `if (x==5)
    8 I0 \- @1 _: K- B1 dcontinue
    ) p4 h( M9 t/ r, Cprintf ("%d",x)0 B  s% w  v# g( u# F1 o: V6 a# C
    }; r: T( N  v+ }0 n7 J3 g
    print ""
    & E0 Y! S  S! ^  C5 \8 {# Y, y/ x+ X}'
    ) I: E+ q6 w9 j0 n& `/ B/ t/ N+ K; q6 E) O# j! q; `% f- x  w( @
    7.7 next 叙述、next file 叙述、exit 叙述# M- b+ D: V* g2 G0 ?) F
    next 叙述强迫 gawk 立刻停止处理目前的记录(record)而继续下一
    ' F; Z' O6 J1 e# D" U个记录。
    1 q  n$ D# b( \+ S, c" onext file 叙述类似 next。然而,它强迫 gawk 立刻停止处理目前* l0 u# e6 z9 x+ {( V
    的资料档。
    * {( q/ L1 z, r& R; Q5 C6 [: @exit 叙述会使得 gawk 程式停止执行而跳出。然而,如果 END 出现
    * e5 `: S; I3 x( b1 q" ?5 q3 O9 a3 \,它会去执行 END 的 actions。' i) h# l% a$ o' _7 {0 O

    2 _: z, E% @  e) Y' X第八章 内建函式(Built-in Functions)
    # Z3 G/ L3 J. y8 N" s" @内建函式是 gawk 内建的函式,可在 gawk 程式的任何地方呼叫内建
    % E% e" S" s2 `7 I$ x0 h/ p函式。
    # z9 w& S+ Z% A1 U: C
    : I$ k3 L& K2 }" `# U! D8.1 数值方面的内建函式
    . h6 c- ?7 y4 Bint(x) 求出 x 的整数部份,朝向 0 的方向做舍去。例如:int(3.9)/ Z) A2 `- f, q. l  M/ |2 V5 E
    是 3,int(-3.9) 是 -3。
    / I4 k3 T( W" @sqrt(x) 求出 x 正的平方根值。例 sqrt(4)=26 K6 [2 s: N0 W
    exp(x) 求出 x 的次方。例 exp(2) 即是求 e*e 。7 t% S% a: Y8 d9 J/ }
    log(x) 求出 x 的自然对数。" t* n& q7 F, {1 S4 y
    sin(x) 求出 x 的 sine 值,x 是弪度量。
    ! j% \7 @- H; ?7 ncos(x) 求出 x 的 cosine 值,x 是弪度量。/ l4 Y% m; x: s
    atan2(y,x) 求 y/x 的 arctangent 值,所求出的值其单位是弪度量。5 x1 P6 Z9 Q" W
    rand() 得出一个乱数值。此乱数值平均分布在 0 和 1 之间。这个
    5 D1 |% o- {: T+ k% ~, ^$ \值不会是 0,也不会是 1。
    1 J5 R& w8 J: u" _% t, S每次执行 gawk,rand 开始产生数字从相同点或 seed。
    0 ?8 h. {8 O) p- Z* [srand(x) 设定产生乱数的开始点或 seed 为 x。如果在第二次你设
    9 C$ V0 v0 k/ w$ b定相同的 seed 值,你将再度得到相同序列的乱数值。+ S. |- K2 _, f" g, \, R
    如果省略引数 x,例如 srand(),则现在的日期、时间会0 n( J0 H; j+ A* o( h! m
    被当成 seed。这个方法可使得乱数值是真正不可预测的。
    8 a% U! W* I9 r) c# e+ w! q3 P: jsrand 的传回值(return value)是前次所设定的 seed 值。
    ! a- g+ e' Y; W4 w# y3 S! r" d
    % H8 _1 _  t2 M1 D8 j8.2 字串方面的内建函式; ?+ g! K0 {2 y
    index(in, find)
    ; Z) H+ h* {& h它会在字串 in 里面,寻找字串 find 第一次出现的地方,传回值是
    ( m* _, o* G. U2 p字串 find 出现在字串 in 里面的位置。如果在字串 in 里面找不到字! |: `! G7 S! n. D; O1 ]4 H' @
    串 find,则传回值为 0。7 Z9 J$ ]; E/ K1 y4 e, a) r1 A
    例如:
    . @7 q3 L! Y! K* Z( Z# Fprint index("peanut","an")
    1 C9 p; j: P' \' R1 U会印出 3。/ x' m6 ?- c0 g8 @
    length(string)
    , C. B  p" [  w2 [2 S求出 string 有几个字元。2 J1 ?) R  X( f5 b4 L* J
    例如:' M+ }/ ]0 h3 ^, J% c
    length("abcde")6 m$ K7 Q+ i, T/ K/ |, Q( D
    是 5。
    # r! W6 o  k1 R' xmatch(string,regexp)
    ) I9 K; \$ r& v# {9 a* jmatch 函式会在字串 string 里面,寻找符合 regexp 的最长、最靠/ a6 y( }) j3 e0 G! g, a2 r( T
    左边的子字串。传回值是 regexp 在 string 的开始位置,即 index' X- Q* G. x' m4 ?( y
    值。
    $ Q- A. k: u( g: a" Qmatch 函式会设定内在变数 RSTART 等於 index,它也会设定内在变/ X# K9 C; p0 d1 T
    数 RLENGTH 等於符合的字元个数。如果不符合,则会设定 RSTART 为; |; o# z- ~, a9 A% B. l5 d' k
    0、RLENGTH 为 -1。9 B3 v$ q$ a/ Q8 B" `, L
    sprintf(format,expression1,...)
    & {! y$ [/ {  A6 z6 b5 H举 printf 类似,但是 sprintf 并不印出,而是传回字串。
    % @( F2 N' o5 ]3 y2 Z例如:/ u+ h' m, z5 x5 S* E! g4 H
    sprintf("pi = %.2f (approx.)',22/7)  P# }6 j% V$ V% _
    传回的字串为"pi = 3.14 (approx.)"
    . @" y  F- I. t6 `7 N' _0 Gsub(regexp, replacement,target)
    . c. Y3 w( K& k  g4 N) T在字串 target 里面,寻找符合 regexp 的最长、最靠左边的地方,
    ; W6 p. y3 q, P! [0 k" b以字串 replacement 代替最左边的 regexp。
    : \3 y" v! N" s1 C0 ^& q例如:& Q, C: `2 p$ l! w7 I/ ?1 p! J7 \
    str = "water, water, everywhere"
    / `1 ~. I. r3 X: L: asub(/at/, "ith",str)  Y. U- A, t0 I9 M. L4 N
    结果字串str会变成0 B# D3 y# Q% U& B) L+ O
    "wither, water, everywhere"
    " E, W& Z: u7 B0 ggsub(regexp, replacement, target)
    1 N- {# i) n3 M8 e9 Jgsub 与前面的 sub 类似。在字串 target 里面,寻找符合 regexp 的& T7 U! Y* m: Y. b5 u
    所有地方,以字串 replacement 代替所有的 regexp。5 `9 T: D) G$ c' C' V; q' q
    例如:- k& @( w* w5 |
    str="water, water, everywhere"
    $ I$ d5 r* V4 D0 kgsub(/at/, "ith",str)
    9 W7 t& ~* ?7 G. w结果字串str会变成
    , s% A- @% K# m% C( f9 Y'wither, wither, everywhere"
    . l$ B, k* F9 D4 W! [) Tsubstr(string, start, length)  z5 }) b* ]( m- u/ I
    传回字串 string 的子字串,这个子字串的长度为 length 个字元,8 J0 E# O) o7 O6 @! R
    从第 start 个位置开始。  y) z- s3 k" Z( J
    例如:
    $ ?5 ]- X3 |. p; G/ Ssubstr("washington",5,3)
    - P9 K7 w1 Z7 O8 r/ t, B传回值为"ing"
    9 ?& f/ v8 G* F2 N3 ~& h如果 length 没有出现,则传回的子字串是从第 start 个位置开始
    % g, K3 Y9 ~9 f. J# Q至结束。' ?' f; p( L% W1 K; W  r% n5 X5 B
    例如:
    . X- t5 D6 f+ F  p+ Lsubstr("washington",5)* x- y" z- o% E8 A% ~3 }* ?
    传回值为"ington"
    $ `' k: l0 q/ L' O9 {% Ptolower(string)" k( k  R' c3 L8 ]4 F* m
    将字串string的大写字母改为小写字母。' ~# {; q# g- j/ e* [# R7 P0 z6 k
    例如:& {- T3 y  _/ {, \; U7 _% [
    tolower("MiXeD cAsE 123")
    # r, l4 `& J3 D$ E传回值为"mixed case 123"8 V' F- Y7 h7 q6 _# {; n
    toupper(string)
    / I$ Q2 k" g, b7 b将字串string的小写字母改为大写字母。
    $ l% v' p  ?/ P- D' S例如:1 ~& z* b( S6 D  M6 L* x
    toupper("MiXeD cAsE 123")% {6 m' u# G- C: b
    传回值为"MIXED CASE 123"
    7 ?- R# F; u1 C, L1 p  x3 k4 r6 H. N3 \  @
    8.3 输入输出的内建函式: L) ]4 D5 U# q9 S% ~
    close(filename)
    + Y8 _. G$ b: l' _% V1 I- ~将输入或输出的档案 filename 关闭。' D' M; e5 `3 n( {
    system(command)
    9 C) y1 ?4 E% w2 c此函式允许使用者执行作业系统的指令,执行完毕後将回到 gawk
    6 U8 i  E: S# |9 X. C程式。
    $ K3 p  y  X, L$ b" j* K3 l# O例如:
    : Z4 X' h0 I8 ?& |0 F# EBEGIN {system("ls")}
    0 v% j6 ^2 J/ x- k0 s  j
    # C5 S0 X+ f& j+ u第九章 使用者定义的函式(User-defined Functions)) p  j7 E) a5 D
    复杂的 gawk 程式常常可以使用自己定义的函式来简化。呼叫使用" |/ y. w8 ]; H0 F5 ^
    者定义的函式与呼叫内建函式的方法一样。
    & q) u$ d- ]( k; A
    - a5 V6 H# {6 \8 L: B( O2 [9.1 函式定义的格式; q: F8 ~7 y- \" ?& X
    函式的定义可以放在 gawk 程式的任何地方。& p% h+ F4 u- E  k" R" F2 V) }! m
    一个使用者定义的函式其格式如下:$ ^$ _, p; P5 L  m4 Q
    function name (parameter-list) {& S+ p7 f# i0 M8 i! n0 C: w: p! j
    body-of-function
    8 n5 [! B3 I* Z* g2 P}# L4 P5 }( Z+ M" O5 N% W
    name 是所定义的函式之名称。一个正确的函式名称可包括一序列的字
    3 o( v7 Y2 v$ m母、数字、下标线 (underscores),但是不可用数字做开头。* o& I& `6 a3 y; Z
    parameter-list 是列出函式的全部引数(argument),各个引数之; F* m" q5 u0 g9 {3 a5 r9 h+ A; C
    间以逗点隔开。! z* }! Q+ U; p% z
    body-of-function 包含 gawk 的叙述 (statement)。它是函式定义
    * w, o5 a- r! x; |+ O' c7 Z里最重要的部份,它决定函式实际要做何种事。+ ?. t+ Z; H# h" ^& ~4 v" F- O
    $ |5 ^. c$ s% x
    9.2 函式定义的例子% E$ i1 z) {& Q" w1 e: h
    下面这个例子,会将每个记录的第一个栏位之值的平方与第二个
    5 C3 L2 W' l7 M栏位之值的平方加起来。
    * W+ {9 e3 g9 h' k* F$ d- r4 u{print "sum =",SquareSum($1,$2)}
    & m7 z% l8 y4 G) Kfunction SquareSum(x,y) {
    ( p/ [* K  x9 O6 }6 b* Usum=x*x+y*y
    6 b. n5 w; H" t* [. r2 Ereturn sum
    4 m$ c* j/ k/ p: X}5 V% g4 m3 d3 ?, U/ [8 d6 O

    . H/ n, G1 F& B* Z2 b& `第十章 □例7 k* Z* h; b0 E1 B5 b
    这里将列出 gawk 程式的一些例子。
    2 x4 v+ A8 D9 u# E* R* D/ Xgawk '{if (NF > max) max = NF}
    : V& g! [% M7 l5 vEND {print max}'
    # Z, |  e( i/ o此程式会印出所有输入行之中,栏位的最大个数。
    2 V8 ^$ r6 r  P$ Igawk 'length($0) > 80'
    . l* R7 _6 N/ Y0 q8 O3 M此程式会印出一行超过 80 个字元的每一行。此处只有 pattern 被  P' z7 W( s; g9 ?. ]: E: L% X
    列出,action 是采用内定的 print。" X# y! p9 K" _; q
    gawk 'NF > 0'
    4 I8 ^  o2 _  V! c对於拥有至少一个栏位的所有行,此程式皆会印出。这是一个简
    , N! u4 q0 C$ T3 m单的方法,将一个档案里的所有空白行删除。
    $ t1 ~, N1 u8 z# q: s/ W  lgawk '{if (NF > 0) print}'4 @* S8 U7 K# `: Y, z- A6 ~6 v
    对於拥有至少一个栏位的所有行,此程式皆会印出。这是一个简
    1 a" [; y% j3 f" P' R( [9 Q单的方法,将一个档案里的所有空白行删除。0 N6 k9 |! X* |+ B" p+ K
    gawk 'BEGIN {for (i = 1; i <= 7; i++)
    * q: ~6 q4 R& G1 |: c: `7 G+ jprint int(101 * rand())}'. h* T( u1 L" f- P, N  G
    此程式会印出□围是 0 到 100 之间的 7 个乱数值。' V% u: s" f; \+ q" O0 s  j5 p) g' v+ o
    ls -l files | gawk '{x += $4}; END {print "total bytes: " x}'
    9 e# S, G; x0 g* d  i6 C6 e4 o$ g此程式会印出所有指定的档案之bytes数目的总和。
      e& ?+ Y: O0 h, R* Rexpand file | gawk '{if (x < length()) x = length()}( @" \0 Z# m8 r2 H- V# B
    END {print "maximum line length is " x}'
    0 }6 u+ `0 X$ g1 t3 @; L5 v" S此程式会将指定档案里最长一行的长度印出。expand 会将 tab 改* s( u1 x0 T3 y0 m: r& N5 O  ]
    成 space,所以是用实际的右边界来做长度的比较。! I. J- c( A. w  H! p
    gawk 'BEGIN {FS = ":"}
    " E2 A  ]8 h: K4 j6 Z( w{print $1 | "sort"}' /etc/passwd
    * w3 _' }6 |, B3 N9 J此程式会将所有使用者的login名称,依照字母的顺序印出。
    5 H$ o7 D$ d$ Rgawk '{nlines++}$ H# R8 U" r( c% D. r9 R
    END {print nlines}'! v- x' q( w1 |
    此程式会将一个档案的总行数印出。2 l9 N5 f2 u) B' y$ T
    gawk 'END {print NR}'
    ; E* n7 s1 a; ], S: k1 y此程式也会将一个档案的总行数印出,但是计算行数的工作由gawk6 f1 y+ z, ~, ?5 F& H5 O8 y6 A  V
    来做。
    : _% O" n7 U& ]1 N2 f* P* \gawk '{print NR,$0}'
    / R9 j# @- t; E4 @4 q此程式印出档案的内容时,会在每行的最前面印出行号,它的功( C' a0 m" t9 h6 _  ^5 \! w2 F
    能与 'cat -n' 类似。% ^  b- c3 _+ \# @
    " s+ D* B2 t/ Y' g$ u
    第十一章 结论
    2 E) z& o( I! _5 ]" s; {gawk 对於资料的处理具有很强的功能。它能够以很短的程式完成3 f+ n% Z8 I4 u0 m  v
    想要做的事,甚至一或二行的程式就能完成指定的工作。同样的一件
    3 f- A. n# T, ^. S1 G- e工作,以 gawk 程式来写会比用其它程式语言来写短很多。  c+ U) o2 S0 e, l) W1 X! G+ _
    gawk 是 GNU 所做的 awk,它是公众软体(Public Domain) 可免费使# |( z& a1 _4 L, M1 B
    用。
    "真诚赞赏,手留余香"
    还没有人打赏,支持一下
    楼主热帖

    相关帖子

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

    该用户从未签到

    尚未签到

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

    本版积分规则

    招聘斑竹

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

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

    Powered by Discuz! X3.5 Licensed

    © 2001-2026 Discuz! Team.

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