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

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

Gawk手册

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

    连续签到: 1 天

    [LV.1]初来乍到

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

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

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

    ×
    GAWK
    2 s& C/ d  Z' R0 {# G第一章 前言5 w2 L$ @8 [+ y( t
    第二章 简介
    9 o: ~( ?: E, c) L$ J5 w第三章 读取输入档案: M; c, H  p/ D4 }% A. S, N- U
    第四章 印出
    5 N, U- u7 R- {第五章 Patterns
    / K9 ?8 H0 |$ ~& P) V: N第六章 算式(Expression)作为Actions的叙述
    2 N2 `; [! {9 C( U第七章 Actions里面的控制叙述: ^1 y5 N2 m- d8 f* f
    第八章 内建函式(Built-in Functions); }8 ]6 N% `  E- x+ w
    第九章 使用者定义的函式5 p2 @# |! T& b, u6 g, w' a
    第十章 □例* Z2 b$ ^4 s5 X% t  i" g7 m
    第十一章 结论
    ! L% I! Y. B9 w" _$ c, G/ ~/ d/ \/ I5 h& @4 u& B
    =======================================( `: _6 V1 u4 p
    第一章 前言
    9 }2 \* ^" g$ l; S( ]awk 是一个程式语言,对於资料的处理具有很强的功能。对於文3 s2 t- \, z- d2 d3 V
    字档里的资料做修改、比对、抽取等的处理,awk 能够以很短的程式8 Q! \" W. X9 }1 P5 H3 P
    轻易地完成。如果使用 C 或 Pascal 等语言写程式完成上述的动作,+ f3 `1 c9 Y, m* I! B$ w& E4 {8 l
    会不方便且很花费时间,所写的程式也会很大。
    4 K. g+ @2 I5 j# Q1 m+ o# C  q  |8 Aawk 能够依照使用者的定义格式来分解输入资料,也可依照使用
    5 O$ Y: c! J' k- Y/ c0 J/ [者定义的格式来印出资料。1 t3 H. [" R0 s6 b' t' M* F
    awk 名称的由来是由它的原始设计者的姓氏之第一个字母而命名
    5 M. e0 E% s, f/ Z:Alfred V. Aho, Peter J. Weinberger, Brian W. Kernighan。
    ; T2 M# o' L" V  ?% T; t) ~+ {$ p; Vawk最初在1977年完成。一个新版本的awk在1985年被发表,它的功能: I5 y+ a9 [1 d9 ~
    比旧版本增强不少。
    ( x$ J" {2 q( J; e7 [& \; b0 \' w0 \7 s' {gawk 是GNU所做的 awk,gawk 最初在1986年完成,之後不断地/ x1 v3 a* v' P# `. L5 o
    被改进、更新。gawk 包含 awk 的所有功能。/ _, }, o- P. J* a
    往後的 gawk 将以下面的2个输入档案来做例子说明。! |! b! Y# [* u) ~  |' K3 S
    档案'BBS-list':
    8 O: t+ o) n- w2 w/ k. i( n5 f# jaardvark 555-5553 1200/300 B* D1 C. w0 M6 w# P2 a8 a
    alpo-net 555-3412 2400/1200/300 A% ]9 j# e+ Q) R* c- a
    barfly 555-7685 1200/300 A$ ]& g0 U4 A- z4 a0 V
    bites 555-1675 2400/1200/300 A6 i4 X' v7 E, V
    camelot 555-0542 300 C
    9 W* k8 r9 F& ^/ p7 jcore 555-2912 1200/300 C
    8 }2 o+ ~: t2 i  x2 dfooey 555-1234 2400/1200/300 B
    9 o9 X7 X( n1 gfoot 555-6699 1200/300 B- }& J0 c% N( V& @
    macfoo 555-6480 1200/300 A
    : L/ C5 f# H& u0 Q' Asdace 555-3430 2400/1200/300 A
    , f2 }# r; c5 \- qsabafoo 555-2127 1200/300 C
      p6 j: U/ D8 U% b& m! Q3 W) b档案'shipped':
    # _8 d5 p0 h" ^- [  JJan 13 25 15 115
    ' I0 Q$ ?+ o. W# `/ BFeb 15 32 24 226
    8 D' p; B/ v" P6 TMar 15 24 34 228: a" h+ P. C$ S8 {& j# c
    Apr 31 52 63 420
    . C( W9 O+ }; n4 _* xMay 16 34 29 208
    # T, B3 [4 K) q6 t: |Jun 31 42 75 4922 T( i7 u. ?# z, x/ }' X+ @
    Jul 24 34 67 436
    + M/ r) ]5 |  k/ q5 u* GAug 15 34 47 316
    ' |/ [$ j+ b! x# }1 ~2 }" S" PSep 13 55 37 277
    0 G1 V" a. Z5 n2 tOct 29 54 68 525& u: v6 \* @7 W1 D
    Nov 20 87 82 577
    3 V: N8 u, H) Z  qDec 17 35 61 401& v3 j/ W2 C* {* v
    Jan 21 36 64 620
    5 D" m4 u: G1 b% [Feb 26 58 80 652" j8 K! u9 L1 Y9 A9 K" V
    Mar 24 75 70 495: j. r1 ]' S  z3 p: q
    Apr 21 70 74 5146 Z1 u$ l2 m2 ^# v
    7 d, X. y: K. W
    第二章 简介8 Y: G; c, p3 V# ?
    gawk 的主要功能是针对档案的每一行(line)搜寻指定的 patterns
    & q1 l3 ?* g! Q, @7 c  m# w/ ~。当一行里有符合指定的 patterns,gawk 就会在此一行执行被指定
    & N5 U7 Q* P: n; F; H, o的 actions。 gawk 依此方式处理输入档案的每一行直到输入档案结) e/ Y7 i/ Q" O+ O& p! I8 F! D
    束。
    ; S; E# P4 m9 Kgawk 程式是由很多的 pattern 与 action 所组成,action 写在- X6 m3 h/ {# {
    大括号 { } 里面,一个pattern後面就跟著一个action。整个 gawk 程8 ?# `! V. C$ b
    式会像下面的样子:. ]. R6 ^- n; @/ i
    pattern {action}/ m  a. l3 Z) I! k9 N; t
    pattern {action}
    6 D" F# e* G& |0 u7 ]: H& c在 gawk 程式里面的规则,pattern 或 action 能够被省略,但
    ; x# j9 e) |. J- ^是两个不能同时被省略。如果 pattern 被省略,对於输入档里面的
    6 t  V) V2 d$ o2 O8 g2 `每一行,action 都会被执行。如果 action 被省略,内定的 action0 Y+ Q" m0 \3 a1 Q! @1 i
    则会印出所有符合 pattern 的输入行。
    * q7 a8 O3 L: i
    % d! f* a7 ^; W/ S" w2 Q) q) p2.1 如何执行gawk程式. G& _" Q3 y8 L7 A
    基本上,有2个方法可以执行gawk程式。
    % i) Q0 A- [' N7 Z' c7 ?□如果 gawk 程式很短,则 gawk 可以直接写在 command line,如下所示:
    ! s& ?8 y2 P7 h* \0 i- W7 _gawk 'program' input-file1 input-file2 ..." @- W! d5 v# P# G/ ~/ d$ w
    其中 program 包括一些 pattern 和 action。" I- w# Z; G" X
    □如果 gawk 程式较长,较为方便的做法是将 gawk 程式存在一个档案,
    % B# g* |! k, g+ K9 n% }- l, N即 patterns 与 actions 写在档名为 program-file 的档案里面,执行7 t1 i" B) f+ J& c: X
    gawk 的格式如下所示:
    9 p2 V7 x0 [- U8 N6 |) j6 {/ rgawk -f program-file input-file1 input-file2 ...7 r, l- d( Q0 `2 A$ E+ b  N
    gawk 程式的档案不止一个时,执行gawk 的格式如下所示:
    2 f+ Y0 a6 {2 X0 N+ Ggawk -f program-file1 -f program-file2 ... input-file1
    $ \* g7 E, j3 W* r$ n' linput-file2 ...
    8 |, _/ x5 t; I" F7 n% O' K* w8 f
    2.2 一个简单的例子
    " i% `& E" }" i+ |, x. a1 [% \现在我们举一个简单的例子,因为 gawk 程式很短,所以将 gawk 程' z& H# v0 ?$ l3 f$ \- J- {
    式直接写在 command line。
    6 Z1 }8 q0 q" w- v2 cgawk '/foo/ {print $0}' BBS-list
    " a# l5 V9 B' i实际的 gawk 程式为 /foo/ {print $0}。/foo/ 为 pattern,意思为搜
    / F, C; Y( ?, f2 E寻输入档里的每一行是否含有子字串 'foo',如果含有 'foo' 则执行 action。  J: Q" z4 g3 z
    action 为 print $0,是将现在这一行的内容印出。BBS-list 是输入的档案。! g' W6 Z: ?+ N: x: u
    执行完上述指令後,会印出下面的结果:
    + D% g! X' `; Q5 _fooey 555-1234 2400/1200/300 B
    ( N! O# v( l2 d  X# X( Cfoot 555-6699 1200/300 B' w# h' P2 _$ I- _( ?: v
    macfoo 555-6480 1200/300 A& h( n  k) g' z/ x6 ~* n9 m
    sabafoo 555-2127 1200/300 C
    4 a; ]5 P( ]' Z. R
    ( K. p" N# J- n- b. ?) ?" B2.3 一个较复杂的例子) ], k3 u4 i8 z3 t6 }
    gawk '$1 == "Feb" {sum=$2+$3} END {print sum}' shipped
    4 L2 F  {: a6 l, o现在这个例子会将输入档 'shipped' 的第一个栏位与 "Feb" 做比较* K% U) \; u, ]1 D' @& V* E! ^
    ,如果相等,则其对应的第2栏位与第3栏位的值会被加到变数 sum。
    ; [2 w) V2 t1 f对於输入档的每一行重复上述的动作,直到输入档的每一行都被处理
    3 e5 w9 R$ B6 D- ]过为止。最後将 sum 的值印出。END {print sum} 的意思为在所有的输
    ) @/ ]# f& t9 ?+ m入读完之後,执行一次 print sum 的动作,也就是把 sum 的值印出。
    8 v) w2 K# H5 X0 U1 v下面是执行的结果:. E: c9 U0 z# }0 Q: t9 J" ^8 |8 m3 k
    842 [9 ~& |* h1 i" T: L7 M

    % E$ l( K. o( r) E$ t" d第三章 读取输入档案; C; J1 |- v# ^6 _$ `( e: Y
    gawk的输入可以从标准输入或指定的档案里读取。输入的读取单% D2 D- i$ B3 T# u, ^: C
    位被称为”记录”(records),gawk 在做处理时,是一个记录一个记
    ) d+ i; G$ P- w2 D' o1 f+ p  c录地处理。每个记录的内定值是一行(line),一个记录又被分为多个
    8 \9 S5 K" J& V" D" D栏位(fields)。. m. ^8 D# I9 q+ V
    7 Q' V8 M+ A, J6 f, R0 d) |
    3.1 如何将输入分解成记录(records)$ B4 m+ W. N0 q6 ^: C. l
    gawk 语言会把输入分解成记录(record)。记录与记录之间是以
    1 G0 }, R9 b4 Y8 Wrecord separator 隔开,record separator 的内定值是表示新一行的! R* `) S9 a, F! J* \' S
    字元(newline character),因此内定的 record separator 使得文字/ o7 r4 ?; q# R
    的每一行是一个记录。
    , [9 ?2 {# j8 g; s3 B& I" Zrecord separator 随著内建变数 RS 的改变而改变。RS 是一个字串,4 B: Q+ x  }, Y. v( Y5 i' W
    它的内定值是"\n"。仅有 RS 的第一个字元是有效的,它被当作 record
    0 D2 ?1 J! d7 Y- F$ e1 Fseparator,而 RS 的其它字元会被忽略。4 W& z! B: l; ?/ M  X' W  }
    内建变数 FNR 会储存目前的输入档案已经被读取的记录之个数。内. |5 x! Y; Y. Q8 K: U7 }' p
    建变数 NR 会储存目前为止所有的输入档案已经被读取的记录之个数。
    $ T3 F! _2 N  l: @$ [% [; H* M, N4 n
    3.2 栏位(field)  O$ J. E0 Y2 ?9 o# y
    gawk 会自动将每个记录分解成多个栏位 (field)。类似於字在一$ t  o" f# O! ~" F
    行里面,gawk 的内定动作会认为栏位之间是以 whitespace 分开。在
    ! R1 }6 D6 f( d( K1 f2 r7 Z7 c, c" Ogawk 里,whitespace 的意思是一个或多个空白或 tabs。2 B# o' A' ^" H6 H, S$ `
    在 gawk 程式里面,以'$1'表示第一个栏位,'$2'表示第二个栏位; X3 [5 X' l8 z4 N
    ,依此类推。举个例子,假设输入的一行如下所示:
    4 v& Y7 f" N; k; {4 `) v2 g6 _This seems like a pretty nice example.
    9 b8 E: f0 g2 f- D" x第一个栏位或 $1 是'This',第二个栏位或 $2 是 'seems',依此类推。
    ) Y3 d* D& E. y* x. o+ p* j4 e" Y有个地方值得特别注意,第七个栏位或 $7 是'example.'而非'example'。. ]1 D+ p# X; `+ t. s
    不论有多少栏位,$NF 可用来表示一个记录的最後一个栏位。以6 m6 D) s! ]9 B* {) A
    上面的例子为例,$NF 与 $7 相同,也就是'example.'。6 M5 b% J, o- J1 N0 {
    NF 是一个内建变数,它的值表示目前这个记录之栏位的个数。
    9 _5 x% g* f  q6 y4 z$0,看起来好像是第零个栏位,它是一个特例,它表示整个记录。
    ( }( r+ k2 B4 k# Z7 t( e: v# O下面是一个较复杂的例子:- F4 z( X  v' ~+ u5 Q
    gawk '$1~/foo/ {print $0}' BBS-list7 a% M4 q( X/ D9 d7 j' y
    结果如下:
    / O! x5 t; M/ X# _" K( b7 ~fooey 555-1234 2400/1200/300 B; [6 q- J' c$ e5 D& j
    foot 555-6699 1200/300 B
    ( |4 ?% Y1 P# b" I) v9 \4 imacfoo 555-6480 1200/300 A
    ) X2 ~5 f; ?. b7 Y* R9 }: ksabafoo 555-2127 1200/300 C
    6 Y, G2 i2 W9 z& O3 m* G" p1 W这个例子是把输入档'BBS-list'的每个记录的第一个栏位作检查,如6 A- C  q2 u; O6 [
    果它含有子字串'foo',则这一个记录会被印出。
    - o9 S1 |3 D, }, j- F- F0 X3 u  o4 r5 @% t% T
    3.3 如何将记录分解成栏位
    2 w# X& m6 i, m; qgawk 根据 field separator 将一个记录分解成栏位。field sepa-
    - ]* \- W9 \+ I1 ]# v$ d9 grator 以内建变数 FS 表示。
      @' i) O# @( A0 k9 r: d2 t举个例子,假如 field separator 是'oo',则下面的行:9 T( s, F& m6 O! A9 o. P
    moo goo gai pan" H$ c. Y: u( d$ q% r
    会被分成三个栏位:'m'、' g'、' gai pan'。  ]3 N7 M3 N: p
    在 gawk 程式里,可以使用'='来改变 FS 的值。例如:- F- M5 z7 |( {- I% @5 J6 p
    gawk 'BEGIN {FS=","}; {print $2}': X( P$ q1 f  z2 K4 W6 f% U
    输入行如下:
    6 Z6 Y) ]: L: o, SJohn Q. Smith, 29 Oak St., Walamazoo, MI 42139" z/ y9 c  E4 J# h- {, }
    执行gawk的结果将印出字串 ' 29 Oak St.'。BEGIN 後面的 action 会在
    $ M) B- }' g( [. K! Q" V, f, t第一个记录被读取之前执行一次。
    - K' r0 k( L6 i+ C6 ^, L
    1 Q" o% R7 ^) u( G第四章 印出
    1 W, d) }/ v& v, L, H% y( T" n6 d& \在gawk程式里,actions 最常做的事就是印出(printing)。简单
    ! Q; }. d. O- r1 Y的印出,使用 printe叙述。复杂格式的印出,使用 printf 叙述。$ h/ A, e+ J& K

    8 ^' `5 S8 x% b) |! }2 @5 j  G$ E: J4.1 print叙述9 M! `4 J( g' E
    print 叙述用在简单、标准的输出格式。叙述的格式如下所示:
    ( e9 Y- _& ~' |6 m/ @print item1, item2, ...
    ; K) p, u. V( U输出时,各个 item 之间会以一个空白分开,最後会换行(newline)。
    0 j; \' J" F* n( O如果 'print'叙述之後没有跟著任何东西,它与'print $0'的效! u: b5 M6 S7 F3 `+ s& X. c6 o, D- Z
    果一样,它会印出现在的记录(record)。要印出空白行可使用'print
    ( u* q& S/ _- `9 O3 r# i/ {4 n""'。 印出一段固定的文字,可用双引号将文字的两边括起来,例如. Q+ v" m- o/ r. @- p! a
    'print "Hello there"'。
    % Y7 C& h" P5 R7 @$ ]" z% Q这里是一个例子,它会把每个输入记录的前二个栏位印出:0 V2 ~. h% {* A6 F( M& {' j
    gawk '{print $1,$2}' shipped
    ' }, f: L3 X5 X+ z8 C. U7 o结果如下所示:
    ! s" N3 h; ^2 N0 n! R6 dJan 13
    ( [: w& z- H  M9 vFeb 15
    1 w% y. h' {: dMar 15
    4 J1 m- u! V5 T( x. r- qApr 31
    2 s; Q( e, X, [) B/ [6 }May 16) N7 k9 l( I) E! I1 l! f$ Y) C
    Jun 31
    - g4 V, q$ A: `9 MJul 24, {! n  U, h- q; x" w  [* g
    Aug 15
    & H4 ~. n  Z9 q% NSep 13
    5 i+ s$ C4 |$ h3 X! a, iOct 29) `4 \/ i- E( ^9 m! n
    Nov 20# N: W7 C! e1 y4 |' l
    Dec 17
    9 X& H9 O" U+ ?% h0 oJan 21
    1 h  w- g# N5 R, ^Feb 26
      C8 ]- A- R9 L1 A0 `: _% T3 {Mar 242 b& |- d9 m- }6 U- u7 P+ A$ Y
    Apr 219 e/ S4 m% b$ v! f* b7 Z

    6 u7 i( G% C6 G4 z4.2 Output Separators
    ; [. g( x; X( k5 u* J前面我们已提过如果 print 叙述包含有多个 item,item 之间; N2 o) I! D( i; i# N2 s4 u
    用逗点分开,则印出时各个item会被一个空白隔开。你能够使用任何+ @- j$ L. ?' S4 Y# w" y* G" ~
    的字串作为 output field separator,可以经由内建变数 OFS 的设
    1 Z" a4 |5 v- G) _! q/ m- F定来更改 output field separator。OFS 的初始值为" ",即一格的
    7 q( U) }' d7 b- V% m空白。
    4 N8 A& V; O% H/ W4 z整个 print 叙述的输出被称为 output record。print 叙述输
    # t7 I; i6 K1 p+ z% h出 output record 之後,会接著输出一个字串,此字串称为 output
    1 G! @) P% o- K) Mrecord separator。内建变数 ORS 用来指明此字串。ORS 的初始值
    : a. U% w& o0 C$ F* W% n为 "\n",也就是换行。
    $ g5 I2 y( L/ A6 k8 \下面这个例子会印出每个记录的第一个栏位和第二个栏位,此二; ^( H) j$ C1 ?* r  ~7 A; L
    个栏位之间以分号';'分开,每行输出之後会加入一个空白行。: Y! z4 ]2 x- @: ^: G
    gawk 'BEGIN {OFS=";"; ORS="\n\n"} {print $1, $2}' BBS-list
    ) |( t; X+ k" O* D# O结果如下所示:) u! a1 Z  C. B2 R2 G
    aardvark;555-5553
    ( Y; {" J, T2 Lalpo-net;555-3412) G: v. c, R- _! J% H
    barfly;555-7685
    : E5 B& P" d2 ?1 J+ Pbites;555-1675
    3 k2 H; c! E( w0 Kcamelot;555-0542
    # r3 p: M$ U, R* N# bcore;555-2912! ?' N+ p. a3 c! A) a: e0 \
    fooey;555-1234/ W9 a/ s) S* l; m/ ]. H
    foot;555-6699
    " }) j, Q/ p3 U& ~2 g& u* N# f7 v" S- ~macfoo;555-64804 i. G7 X, S5 M9 a$ v
    sdace;555-3430
    ' }5 O6 N$ p3 \sabafoo;555-21274 B! G. x3 z* I/ ]

    2 _) J8 h0 X6 z  M' J4.3 printf叙述
    " `- J5 x8 O' Aprintf 叙述会使得输出格式较容易精确地控制。printf 叙述可以
    ! C% C% |9 I% i指定每个 item 印出的宽度,也可以指定数字的各种型式。0 A/ V3 K8 h" {! Y% G8 B! r1 |6 g
    printf 叙述的格式如下:
    . t: I9 A* B* I  ?' D- W+ v2 I+ T1 o; \printf format, item1, item2, ...
    0 B  q3 Z) L) _# I# yprint 与 printf 的差别是在於 format, printf 的引数比 print+ f" V: D  K7 `5 _* o
    多了字串 format。format 的型式与 ANSI C 的 printf 之格式相同。
    ! y$ `  m* q' v* K4 k# |6 Uprintf 并不会做自动换行的动作。内建变数 OFS 与 ORS 对 printf 叙
    ( V  h% ^, t. w9 [述没有任何影响。
    ! o3 h; m1 d% _3 A9 T/ S& Y, S, Q格式的指定以字元'%'开始,後面接著格式控制字母。
    , z8 `- Z3 h5 h格式控制字母如下所示:5 {+ ^* @  k: M" u* M8 Q
    'c' 将数字以 ASCII 字元印出。
    * {6 c3 v0 H1 L8 B( Y; J例如'printf "%C",65'会印出字元'A'。
    7 S( y' t7 M7 {' J9 p'd' 印出十进位的整数。8 T! _% }+ z  p2 A1 Z$ P0 I; ^
    'i' 印出十进位的整数。
    # Y- l4 F6 Z4 Y& [8 T'e' 将数字以科学符号的形式印出。4 w; D/ @; ~4 a/ F2 x3 g% \: ~
    例如
    ( O: r& o" w; z% f7 L6 o+ Xprint "$4.3e",1950$ C; c0 l. E* a* |
    结果会印出'1.950e+03'。/ S/ p% V0 j% L9 O$ D) t6 T
    'f' 将数字以浮点的形式印出。
    0 m" ~; M/ U( N1 G'g' 将数字以科学符号的形式或浮点的形式印出。数字的绝对值如果
    0 s4 F; X# w+ q8 G. O+ R* _! N大於等於0.0001则以浮点的形式印出,否则以科学符号的形式印: Z4 Y) [/ @* G' r% {# i, s! {
    出。
    ! w/ E6 C1 Q7 |; j6 z& t'o' 印出无号的八进位整数。
    . S$ ~2 P/ N2 Y* I8 z's' 印出一个字串。
    : Q( J4 ]6 B) C8 K4 m'x' 印出无号的十六进位整数。10至15以'a'至'f'表示。
    3 G4 o: z8 z' }' q'X' 印出无号的十六进位整数。10至15以'A'至'F"表示。$ }2 ~( S+ f& V% U/ Q
    '%' 它并不是真正的格式控制字母,'%%"将印出"%'。
    3 G& I/ {9 ?) l1 I在 % 与格式控制字母之间可加入 modifier,modifier 是用来进一
    ! O* h+ P$ j; S1 e1 {; u& \) F% j步控制输出的格式。可能的 modifier 如下所示:. p- c" H# V0 M! P" n- n
    '-' 使用在 width 之前,指明是向左靠齐。如果'-'没有出现,则会在8 e; v" W  w4 H6 M, s) g: }
    被指定的宽度向右靠齐。例如:* h& t4 R5 m8 R" j+ Y; E7 S
    printf "%-4S", "foo"
    3 g$ _  B6 V2 F; U& e1 k- ?' ~会印出'foo '。" r1 S5 z, q- i2 C! p  K8 s
    'width' 这一个数字指示相对应的栏位印出时的宽度。例如:
    1 n+ A1 U+ p, r0 z1 u- [' Bprintf "%4s","foo"
    7 S" c/ P/ P- M( d会印出' foo'。
    * M: @. A* n$ |# e1 H6 ?width 的值是一个最小宽度而非最大宽度。如果一个 item 的7 n3 m7 v4 I( G# Q0 O# x
    值需要的宽度比 width 大,则不受 width 的影响。例如) L% E/ q" w6 L( \( M8 [& W
    printf "%4s","foobar"9 ]' K; H' a3 v) h4 ?
    将印出'foobar'。7 i  \2 i# n; a  |4 {
    '.prec' 此数字指定印出时的精确度。它指定小数点右边的位数。如
    3 F  F* D7 P- E: K( a/ ]果是要印出一个字串,它指定此字串最多会被印出多少个字
    ( P0 ?6 \2 n  j, j6 h& i元。
    ; y2 D$ S6 W9 q$ i) [3 s+ x, j
    & G0 E, `* r* c0 F1 C7 a( {! n: D第五章 patterns
    5 P, }7 j2 E" M$ j  g! e在 gawk 程式里面,当 pattern 符合现在的输入记录(record),其
    3 G! y: x- O( M) k' J% ?, k7 k& s相对应的 action 才会被执行。5 Q4 R; N& O1 r, L! I1 t
    3 `4 y0 a! u4 i+ S
    5.1 Pattern的种类1 K6 Q! C# y: f  E+ V) q2 E
    这里对 gawk 的各种 pattern 型式作一整理:
    . q9 `! Q) p' r1 [, \/regular expression/5 p! m+ O" z. r% u0 q5 _
    一个 regular expression 当作一个 pattern。每当输入记录 (
    , }: [# j8 x, lrecord)含有 regular expression 就视为符合。
    + k6 L* g2 _9 n5 r9 E/ t& J& Kexpression7 w: `7 u- L; F+ `7 P# u% L
    一个单一的 expression。当一个值不为 0 或一个字串不是空的,+ K" X# u* c. f$ L( ?' g
    则可视为符合。& l6 |3 ^/ Z- A( T% c' y: V$ V
    pat1,pat2( H3 H5 N6 j& u  T& F$ g
    一对的 patterns 以逗号分开,指定记录的□围。( C' v1 v( o" P- U- ?
    BEGIN' ]- g" x" O, ]0 e- b, ]0 d
    END
    ; u: U" q* U- o' z. S这是特别的 pattern, gawk 在开始执行或要结束时会分别执行相
    $ o8 v4 y9 Q) a" @对应於BEGIN或END的 action。) C, I  r8 \* g+ M+ G
    null3 B8 E3 F3 A- O3 O6 y
    这是一个空的pattern,对於每个输入记录皆视为符合pattern。
    0 h" e% S4 M. @/ o6 D% M
    : _9 A' Z+ R) u" d7 ]+ E2 s5.2 Regular Expressions当作Patterns
    $ K* R$ L% Y8 a  b0 y5 j) n8 P* v一个 regular expression 可简写为 regexp,是一种描述字串的方3 e+ I7 }3 G5 c
    法。一个 regular expression 以斜线('/')包围当作 gawk 的 pattern。
    3 Z, l' V/ ~8 K- T5 ^! i如果输入记录含有 regexp 就视为符合。例如:pattern 为 /foo/,) c2 W9 ^) ~2 \0 {) i2 {2 @6 \
    对於任何输入记录含有'foo'则视为符合。
    ) ~; f) x5 B7 `" O' l下面的例子会将含有'foo'的输入记录之第2个栏位印出。
    : |9 t$ ~7 ~4 qgawk '/foo/ {print $2}' BBS-list, j* X$ Q. x- w
    结果如下:. B: ]/ L: O: b0 R+ y
    555-1234$ w0 l5 J$ m, Q& g- e  t9 \% I" V4 |
    555-66997 I! z" \+ q# {% @
    555-6480
      u* N: W0 L: H4 d% t' w6 x555-21271 c& O9 `- i* R% }# d
    regexp 也能使用在比较的算式。/ F' W" g9 w6 |" V( R4 f
    exp ~ /regexp/
    % D0 [- e, \  A4 J如果 exp 符合 regexp,则结果为真(true)。8 ]6 k2 c% W4 g
    exp !~ /regexp/; w7 P- g: |. e+ [
    如果 exp 不符合 regexp,则结果为真。
    8 O2 w) e% _; i4 J) Y% Z8 F7 e5 Z/ R9 f' S3 I; x
    5.3 比较的算式当作Patterns" @8 y! d/ G* `% d8 J
    比较的 pattern 用来测试两个数字或字串的关系诸如大於、等於+ y, C  O6 u6 p
    、小於。下面列出一些比较的pattern:
    + Q+ [, ^, Y8 @* j- p. Z3 _  mx<y 如果 x 小於 y,则结果为真。
    3 J; u5 E6 y  W2 T  H5 hx<=y 如果 x 小於、等於 y,则结果为真。
    , K' x6 p$ d0 J: Hx>y 如果 x 大於 y,则结果为真。$ a* c3 G) a) J$ F2 m2 M/ W: r
    x>=y 如果 x 大於、等於 y,则结果为真。* A) ^3 q3 I3 w/ I* _/ e
    x==y 如果 x 等於 y,则结果为真。( N- J6 Y! `! l4 p
    x!=y 如果 x 不等於 y,则结果为真。
    - l2 I7 L0 d" ~! G) D( k1 K" V  Px~y 如果 x 符合 regular expression y,则结果为真。
    ! X( M$ X/ p. n$ Wx!~y 如果 x 不符合 regular expression y,则结果为真。% D  C" O( B4 O; q
    上面所提到的 x 与 y,如果二者皆是数字则视为数字之间的比较,9 B4 b- n) `# m* K4 D0 W5 b
    否则它们会被转换成字串且以字串的形式做比较。两个字串的比较,
    - e+ C' a2 g; K  D  r会先比较第一个字元,然後比较第二个字元,依此类推,直到有不同; E% l& v3 |7 O
    的地方出现为止。如果两个字串在较短的一个结束之前是相等,则视" O# l* h" p3 n$ L; O* \; k% Q
    为长的字串比短的字串大。例如 "10" 比 "9" 小,"abc" 比 "abcd" 小。
    9 i$ D$ R0 e- {9 v6 G  L; ]# @
    5.4 使用布林运算的Patterns
    + R, F7 A; |$ b8 G8 I一个布林(boolean) pattern 是使用布林运算"或"('||'),"及"+ Z4 m" b! f. P( m2 G
    ('&&'),"反"('!')来组合其它的pattern。
    5 a0 Q- R/ e* r9 J7 B例如:% u5 }+ u" i- G1 y
    gawk '/2400/ && /foo/' BBS-list& s0 x8 k4 ?- E* {' ]7 z% h
    gawk '/2400/ || /foo/' BBS-list4 x  @, }$ O- C4 {1 g
    gawk '! /foo/' BBS-list! F: u$ n' E( Q5 L
    : g' Y- w2 k! P7 u, ^9 c; B+ s
    第六章 算式(Expression)作为Actions的叙述
    ; _% Q6 b9 U$ |1 U0 m算式(Expression) 是gawk程式里面action的基本构成者。( E; C6 M; G6 U. m
    ; U8 n  x- s- ~% b# m6 z0 O
    6.1 算术运算
    2 `/ O) P5 R2 l: E# Fgawk 里的算术运算如下所示:7 {1 ~  K- o' ?* e- u( Q
    x+y 加0 _- q4 \2 S! J- ]7 E1 q
    x-y 减
    , U! A. g" k5 F, z-x 负$ t2 X# S( y) p2 |& c
    +x 正。实际上没有任何影响。
    6 K$ U, k. Y+ r8 v# r4 |! nx*y 乘
    : |3 g$ {* p/ A5 T8 sx/y 除) x$ U  h- z& v$ Y8 `( k1 a2 y+ }  e
    x%y 求馀数。例如 5%3=2。
    : w0 Y  Z4 V% M* r9 px^y
    * |: J/ X, a0 n7 ~x**y x 的 y 次方。例如2^3=8。
    . Q7 Z# Y9 K$ q  P4 s
    * c# b1 X9 x& N! h+ }6.2 比较算式与布林算式
    ; p- s9 k9 ?( ?: ?比较算式 (comparison expression) 用来比较字串或数字的关系  u5 m" D  c% F
    ,运算符号与 C 语言相同。表列如下:
    0 Z6 }! C" Z; |" ?4 V# n. ix<y& _! g6 w" |, m$ q0 f8 {
    x<=y- U" Y# K' f# L3 j& j7 U
    x>y8 s' |/ Z) I2 i5 P
    x>=y
    # Z$ Z$ ]5 Z; h; o9 |$ Ax==y
    : J% i' d3 N2 j. T0 K9 v$ b& ?, Gx!=y
    $ \- O/ u' |, g& n' x" ~% L7 Wx~y3 B" `# e# o3 f
    x!~y# ?  y* w0 q1 j' `* S
    比较的结果为真(true)则其值是 1。否则其值是 0。4 X0 i/ ~2 N& {5 t! E
    布林算式(boolean expression)有下面三种:
    , q  E7 {% w* vboolean1 && boolean2
    % Z( o2 w( C. A9 jboolean1 || boolean2$ w8 g2 F' E: m
    ! boolean$ m1 @0 L  e8 H, S8 l0 L) A  p

    / z3 N3 S0 S' R; N2 d6.3 条件算式(Conditional Expressions)
    * J; e1 v7 \! B+ K一个条件式算式是一种特别的算式,它含有3个运算元。
    0 p- {& J& V" O0 r( G条件式算式与C语言的相同:# D; h8 L: R* C/ v  \* ~: {
    selector ? if-true-exp : if-false-exp
    , L$ h# {5 W: O1 h" j它有3个子算式。第一个子算式selector 首先会被计算。如果是真,# t9 R6 Y# P; i% h! d
    则if-true-exp会被计算且它的值变成整个算式的值。否则if-false-4 W$ Y4 C. }0 x# U& r  d
    exp 会被计算且它的值变成整个算式的值。. c; C2 E2 W& z0 m
    例如下面的例子会产生x的绝对值:& |& ~  m( l# K+ j
    x>0 ? x : -x
    ' V9 @8 \( G' v% a$ f  G9 X7 m- w3 {
      K# f$ l; T' I, t2 a- k" m$ h第七章 Actions里面的控制叙述
    + e0 |7 w4 q' [在 gawk 程式里面,控制叙述诸如 if、while 等控制程式执行的流# U1 `8 i' b  d- h6 o1 Q
    程。在 gawk 里的控制叙述与 C 的类似。0 I" Q9 m" }4 m: S
    很多的控制叙述会包括其它的叙述,被包括的叙述称为 body。假' X% i: J# N4 X- C# h' s
    如 body 里面包括一个以上的叙述,必须以大括弧 { } 将这些叙述括起
    8 k" e$ [0 a" u% {( K/ O来,而各个叙述之间需以换行(newline)或分号隔开。
    ; {# O: u4 G2 P) u/ r4 V) I! Y
    5 Q/ R* s% E+ k. |) C7.1 if 叙述, n) e) |7 y, \+ d' h: A& h& E
    if (condition) then-body [else else-body]
    ) F2 w" \0 m% c/ k& A' n2 i如果 condition 为真(true),则执行 then-body,否则执行 else-body。
    - d& s( p+ @! d+ `举一个例子如下:
    5 @/ [: V" g$ Z) x6 \4 K& Lif (x % 2 == 0)( c- t5 ^* M% k0 m* C* e/ F
    print "x is even"
    8 a. t1 W7 `* m4 B% ielse$ X! G& [4 L5 c) ?
    print "x is odd", E) E1 G& d: V
    & C/ G6 I9 _1 D* C2 f
    7.2 while 叙述
    $ k3 L; l8 m# I0 q& F8 J+ |9 Ewhile (condition); g3 I0 ]8 k" |; {1 L
    body
    2 ?, z) k' H6 @' Dwhile 叙述做的第一件事就是测试 condition。假如 condition 为真则- q! g) g2 H! Y: O0 _, _
    执行 body 的叙述。body 的叙述执行完後,会再测试 condition,假如
    / o6 d* A+ d4 l' y, U! Y" Fcondition 为真,则 body 会再度被执行。这个过程会一直被重复直到7 V/ N$ g, N7 I5 m, p
    condition 不再是真。如果 condition 第一次测试就是伪(false),则/ d' ?8 B* _0 E" v4 ?
    body 从没有被执行。
    ( F" D0 ?# `- ^3 ?) n下面的例子会印出每个输入记录(record)的前三个栏位。
    * p8 X5 \7 v3 g+ P& o( |8 ogawk '{ i=1
    # u/ A% ]" X/ P! Z6 ]while (i <= 3) {
    / z) v9 d; f' n, O- M6 R9 cprint $i, M0 M$ a  E1 t6 `8 e+ F+ L
    i++
    / B7 [) ]1 E( H  \5 p- l7 d}0 e  z) E5 c! I8 d: l9 M! T; ~
    }'
    $ A2 D4 T$ `2 T- g
    " i+ U9 C4 r6 ]7.3 do-while 叙述' D( v9 Z3 O- Y# q+ S) c' L
    do
    # c6 S5 D- w" A4 Ibody$ G3 V; V' y5 ~$ a$ D
    while (condition)
    2 q8 l& R& [& F3 x; \" ^! s这个 do loop 执行 body 一次,然後只要 condition 是真则会重复执行 body。
    " `! }: D. q$ b& Y0 I9 X9 A即使开始时 condition 是伪,body 也会被执行一次。. O7 X5 g2 r2 Q3 b! }, M) N
    下面的例子会印出每个输入记录十次。0 G0 u' w: @% G$ ?
    gawk '{ i= 17 M& Y' M8 Q5 \
    do {9 r+ Q3 r% {# m% G* J
    print $0
    # K! N; U8 C; W# o0 R+ ~) B, Ui++
    ! w( _- k7 N8 x( u, k} while (i <= 10)* R- ?6 l4 A+ q& H
    }'' X2 U! A7 m) m; H

    . D9 S; Z% ^: s# E0 _7.4 for 叙述+ f/ Z# l* Y9 D0 s
    for (initialization; condition; increment); r2 f+ S+ W# [7 m
    body
    8 l: H9 @: N$ C6 O此叙述开始时会执行initialization,然後只要 condition是真,它2 \$ V1 O  p8 R% f
    会重复执行body与做increment 。
    9 H. J, U. P2 @, ?- Y( w下面的例子会印出每个输入记录的前三个栏位。
    5 \6 T. m/ v7 l- L4 jgawk '{ for (i=1; i<=3; i++)
    7 l, G. P! X3 N$ o! s+ Jprint $i- H+ T' u5 J; G
    }', l1 d: O8 ~2 E* e6 D7 j

    / f9 v% f: F: v7.5 break 叙述
    9 ~5 l: i- C/ L- U9 {$ Mbreak 叙述会跳出包含它的 for、while、do-while 回圈的最内层。
    ' k& E6 v) z1 P' W% U6 U下面的例子会找出任何整数的最小除数,它也会判断是否为质数。
      g5 \: L/ G2 M0 y( kgawk '# find smallest divisor of num
    ' t( F' d; N  ~& a2 d+ p{ num=$1. D% C; X6 _, |$ ]1 Q2 G2 x
    for (div=2; div*div <=num; div++)0 G, l  [$ p+ N& c7 l
    if (num % div == 0), z" B) S8 I6 P0 T2 D2 J+ f
    break1 I. u9 ]9 Z0 \6 D5 {' h  }9 T
    if (num % div == 0)
    ; T5 N' U; u- _9 {  Jprintf "Smallest divisor of %d is %d\n", num, div& v) y0 A9 S2 I* U( t
    else- I  m9 f7 N+ K0 d, n1 ]
    printf "%d is prime\n", num }'5 h7 B" [1 h  J- |; _5 E
      g% [  ~0 J) m2 w6 j+ ?2 `
    7.6 continue 叙述2 Y9 u# K" o) ], {+ k$ @
    continue 叙述使用於 for、while、do-while 回圈内部,它会跳7 s8 r2 J" i" X* E8 n& [9 O; b
    过回圈 body 的剩馀部分,使得它立刻进行下一次回圈的执行。& f4 ~, v/ T/ l/ N1 n. N" ?# I
    下面的例子会印出 0 至 20 的全部数字,但是 5 并不会被印出。% V- k8 O8 m  o. O9 X
    gawk 'BEGIN {
    & F, q  j! B! [0 E5 Q' q" Sfor (x=0; x<=20; x++) {
    - a/ Y3 e1 P- Iif (x==5)
    0 x# x  a0 G* G2 F, Icontinue
    - }8 [3 V- Q, J1 {# J% gprintf ("%d",x)
    9 H% s; S. v: w% C* c}
    : s5 i6 d7 G$ `* n' Gprint ""
      h. B) Q" B7 t1 G7 q9 c}'
    2 d0 t% k; ~+ x/ v5 j6 M3 F8 Y3 c6 c# w
    ' v- u, A  o% i2 m! H" h8 S4 \7.7 next 叙述、next file 叙述、exit 叙述
    2 Q/ k% }; |  ]& U% @% n: @. w; L  p5 Nnext 叙述强迫 gawk 立刻停止处理目前的记录(record)而继续下一4 w) x5 C& c$ a3 Y% H
    个记录。
    / J- H4 D4 U; s7 i7 inext file 叙述类似 next。然而,它强迫 gawk 立刻停止处理目前
    ) e7 Y2 \' g/ k3 t1 h) `的资料档。6 i" D  y, n4 j4 C9 q' d3 `
    exit 叙述会使得 gawk 程式停止执行而跳出。然而,如果 END 出现
    1 {  |8 Q+ t$ V' o6 u6 W4 Q,它会去执行 END 的 actions。
    ; N5 n5 q2 N; ]
    9 q+ K# X5 `- Z9 M6 u& @第八章 内建函式(Built-in Functions)
    ' B" w, M& \: L6 e0 C1 r内建函式是 gawk 内建的函式,可在 gawk 程式的任何地方呼叫内建
    " K% i/ `" E& j' A. W3 K6 i' J函式。
    ; ~' V3 J0 l& z. ?- U$ i  N* f+ b3 W
    8 g5 \/ b& d1 M7 y0 U2 M) L* N8.1 数值方面的内建函式- t: j; @+ y$ Z
    int(x) 求出 x 的整数部份,朝向 0 的方向做舍去。例如:int(3.9)
    9 `6 e& Y; z% X. j" q是 3,int(-3.9) 是 -3。, Z! x; ]) J, k9 Y; {3 \( o2 [
    sqrt(x) 求出 x 正的平方根值。例 sqrt(4)=2
    ! g3 \- W  ?6 `! e! g! Texp(x) 求出 x 的次方。例 exp(2) 即是求 e*e 。  {' x% K1 O* ]1 K4 T1 a8 w
    log(x) 求出 x 的自然对数。
    4 P& R4 L1 v4 ]. bsin(x) 求出 x 的 sine 值,x 是弪度量。8 l2 a5 c; x' @) D" r
    cos(x) 求出 x 的 cosine 值,x 是弪度量。: f0 Q" R6 Z. X+ h) [, u' @1 Q
    atan2(y,x) 求 y/x 的 arctangent 值,所求出的值其单位是弪度量。% r$ `+ ]7 Y$ E) V" |9 B( K
    rand() 得出一个乱数值。此乱数值平均分布在 0 和 1 之间。这个
    0 G% p/ a' v, c; S0 V  S6 ~值不会是 0,也不会是 1。, J, l* Q. X5 v) d2 F: H. g5 G
    每次执行 gawk,rand 开始产生数字从相同点或 seed。
    , F5 m9 X" X7 t5 m( B2 }9 Qsrand(x) 设定产生乱数的开始点或 seed 为 x。如果在第二次你设4 e& o% N9 h9 f3 e' a; F
    定相同的 seed 值,你将再度得到相同序列的乱数值。4 b" G- c( u/ V9 g7 ^, K/ }+ F
    如果省略引数 x,例如 srand(),则现在的日期、时间会7 i% k7 i# o6 Q: a, j
    被当成 seed。这个方法可使得乱数值是真正不可预测的。; r: R) G' f! r) e5 K
    srand 的传回值(return value)是前次所设定的 seed 值。4 V) t0 T) M* s& Q
    ! y( d! i; q4 ]6 c, |2 w
    8.2 字串方面的内建函式9 M0 m9 N8 `& f; B5 n9 B8 G
    index(in, find)
    " l% F1 N4 U7 q它会在字串 in 里面,寻找字串 find 第一次出现的地方,传回值是* V6 B4 d' b& ]/ Z  O
    字串 find 出现在字串 in 里面的位置。如果在字串 in 里面找不到字3 h+ I+ W% S6 O: m8 p# e$ y' Z6 U
    串 find,则传回值为 0。
    ( J( J+ M; V2 m& q7 }$ b* \; n+ z! q例如:9 {! M$ q, Y$ h/ ]0 Y, v
    print index("peanut","an")5 R' P; N- P$ `
    会印出 3。
      X. J4 M) G  U$ {9 Flength(string)7 N8 |1 e; s  @  V; `+ j
    求出 string 有几个字元。" U" ~2 \- b( C
    例如:% `0 V/ u- t6 m$ C1 L% a
    length("abcde")& \9 y1 K+ q' D6 V0 D
    是 5。  E# @1 R3 N. C' s& x
    match(string,regexp)
    9 e' @" Y; O9 j9 imatch 函式会在字串 string 里面,寻找符合 regexp 的最长、最靠
    5 c9 O6 g* s! Q左边的子字串。传回值是 regexp 在 string 的开始位置,即 index
    # ~- `: `  v) M8 L1 S# n7 o值。& t8 a8 u8 C7 k: \+ }& m. a
    match 函式会设定内在变数 RSTART 等於 index,它也会设定内在变: Y+ t: `% J- }# l5 P+ S
    数 RLENGTH 等於符合的字元个数。如果不符合,则会设定 RSTART 为
    6 J5 `# e  d0 [+ b+ \5 F  z0、RLENGTH 为 -1。; }# K( E5 S" L; p) A
    sprintf(format,expression1,...)
    ' o$ Q( Q% v; S举 printf 类似,但是 sprintf 并不印出,而是传回字串。
    / ]$ y& q( a3 O' B例如:
    $ K9 Z$ r  W+ @; M4 y7 bsprintf("pi = %.2f (approx.)',22/7)! H2 i5 e. w8 o# W# J
    传回的字串为"pi = 3.14 (approx.)"
    + H6 x8 j6 _2 i0 n( Z! Bsub(regexp, replacement,target)- h( B7 d" Z) J/ D8 ?2 q/ R  t
    在字串 target 里面,寻找符合 regexp 的最长、最靠左边的地方," U! [7 j& l6 P$ H
    以字串 replacement 代替最左边的 regexp。
    ) ~& f; B0 p6 T. `例如:
    , x1 R/ V% s5 T2 Bstr = "water, water, everywhere"
      \& d- k, O6 i) \9 {3 P3 Tsub(/at/, "ith",str); O* O/ B4 i6 N
    结果字串str会变成
    7 i6 h6 ^/ r7 Z"wither, water, everywhere"0 }; [$ S) s. @) R3 r& \
    gsub(regexp, replacement, target)
    2 k. V* o2 ~7 bgsub 与前面的 sub 类似。在字串 target 里面,寻找符合 regexp 的
    - R, x- X# \. ^所有地方,以字串 replacement 代替所有的 regexp。! h& z! f) Z, @" d3 b5 d
    例如:  P, N9 O4 c! b' C9 B" K
    str="water, water, everywhere"
    # s  ~% ^2 f, g* N: b, Dgsub(/at/, "ith",str)9 }0 v( h$ R$ A) V: x1 m
    结果字串str会变成
    ' l: R8 O( O/ X1 f0 Y  P: c/ n/ r'wither, wither, everywhere"# y0 y# e* D1 x
    substr(string, start, length)! B, d8 ~/ H  m! C# l0 u
    传回字串 string 的子字串,这个子字串的长度为 length 个字元,
    ' @. |$ u, [' M6 v0 m从第 start 个位置开始。
    ' z, f8 Z2 }( o" p- g: @例如:
    9 z; i7 h6 U; @6 @% [substr("washington",5,3)9 R/ ]$ Y* h, E
    传回值为"ing"2 w& [* X- R2 y8 ^6 d! L
    如果 length 没有出现,则传回的子字串是从第 start 个位置开始
    1 X5 ]4 G2 u( R4 L至结束。
    . ]( p) Y' C) @4 u例如:
    $ C) I" @0 N/ P7 Jsubstr("washington",5)1 ?1 D- E4 O+ C5 h  x' z3 `0 K. \, |
    传回值为"ington"  j" a" T6 O/ h3 m
    tolower(string)
    / U! T/ e& O9 x. _将字串string的大写字母改为小写字母。
    + B* P$ _/ W8 J/ F$ y& F, h5 E) {4 V例如:
    . _6 F1 d/ d+ _$ V/ [tolower("MiXeD cAsE 123")5 j: ^. g. {8 `6 Z8 ^
    传回值为"mixed case 123"
    ; C' l5 Q) j4 y$ W+ Htoupper(string)
    / r. N" ~" ^0 a/ R& A将字串string的小写字母改为大写字母。* W! G5 @# s4 w( k
    例如:& q; T. f0 ^3 M' S2 M
    toupper("MiXeD cAsE 123")' k# X+ e; k3 g/ }5 F
    传回值为"MIXED CASE 123", F' x; J" `% u  E% Q  b6 u
    % R4 K1 B! |0 X7 L* T
    8.3 输入输出的内建函式/ n& o: z& |: Y( M! H; H
    close(filename)
    $ B$ `. o: T) v. I将输入或输出的档案 filename 关闭。8 `% F1 i+ B' B) M' j* X8 ?
    system(command)9 ~/ C! G* e) A$ f8 `' p$ b+ H. x
    此函式允许使用者执行作业系统的指令,执行完毕後将回到 gawk. y9 g% w* S/ @2 f0 h
    程式。
    - j! t& F) U' J( ^9 q例如:$ _8 Q3 a$ g, j  z& J1 n
    BEGIN {system("ls")}! f+ y" i: c9 P
    % w3 Y& U$ m6 y4 a1 O5 d
    第九章 使用者定义的函式(User-defined Functions)- d( r3 c! e( m5 _& K7 H3 i
    复杂的 gawk 程式常常可以使用自己定义的函式来简化。呼叫使用
    2 X2 `9 ^: m3 n1 L9 W4 |3 e" V者定义的函式与呼叫内建函式的方法一样。* K4 I; S# C+ U2 d0 [% h2 U  N. D

    4 v( h- w) S; M9.1 函式定义的格式1 q3 e5 e5 L- H+ U7 a
    函式的定义可以放在 gawk 程式的任何地方。# S* G  r; b1 N5 ?/ m  A! a
    一个使用者定义的函式其格式如下:
    " ^& j: Z0 q+ o( ^+ Z0 `; K  O/ [function name (parameter-list) {, S! \5 \8 y# t" N* Y5 w0 p; E
    body-of-function& b9 O2 V' d( T4 R: i. P
    }
    + q* E, t, s4 |$ ?: n* R0 iname 是所定义的函式之名称。一个正确的函式名称可包括一序列的字7 o" ^4 v5 ^. Z
    母、数字、下标线 (underscores),但是不可用数字做开头。
    5 c9 i0 E! h$ G; O8 P- Kparameter-list 是列出函式的全部引数(argument),各个引数之
    6 n5 h0 u" y& C* c间以逗点隔开。& ~9 ^& w( t& P- Z5 \7 H
    body-of-function 包含 gawk 的叙述 (statement)。它是函式定义
    : X4 B; G) B1 T. Q/ z里最重要的部份,它决定函式实际要做何种事。
    ' x% ?5 v# Q% s- K8 @* y9 m" Q
    5 e; W' ?& z" H- W9.2 函式定义的例子6 Y6 A$ m5 d6 G, G8 `1 e4 M% D
    下面这个例子,会将每个记录的第一个栏位之值的平方与第二个
    - s+ W1 o- [: e栏位之值的平方加起来。% M4 E" Q  B' _8 X$ }/ d
    {print "sum =",SquareSum($1,$2)}) w4 P9 [" |$ i
    function SquareSum(x,y) {
    1 F( C" Q% ^: c( I8 v4 j" n9 isum=x*x+y*y0 a1 n& |0 x: b
    return sum
    9 ]' A5 X6 k" N}
    6 J0 n2 ]* w" q- B2 f9 H# F$ a3 j" |" T/ l8 h
    第十章 □例
    * W% P2 [/ U% ]( K9 b这里将列出 gawk 程式的一些例子。
    3 ?3 U' V! f% \5 O/ f& m5 hgawk '{if (NF > max) max = NF}& V/ q+ G9 e+ n4 X( K
    END {print max}'7 c3 t/ k8 e; [" I
    此程式会印出所有输入行之中,栏位的最大个数。
    ) m& W2 H' ^: K8 m3 K$ I" O6 }gawk 'length($0) > 80'
    , D1 ~2 e+ Q4 M. X此程式会印出一行超过 80 个字元的每一行。此处只有 pattern 被2 O1 g, z) h9 f$ H7 \; q( ]
    列出,action 是采用内定的 print。
    + H8 u. P1 r' r/ Y6 i: _, D! vgawk 'NF > 0'
    - f; q# U, M; M% _; X% Q对於拥有至少一个栏位的所有行,此程式皆会印出。这是一个简5 E; }- T: _7 e/ L% s
    单的方法,将一个档案里的所有空白行删除。
    ; w! Q1 W# ]4 ^3 Wgawk '{if (NF > 0) print}'
    & p# G( F; J8 V. G对於拥有至少一个栏位的所有行,此程式皆会印出。这是一个简  E* n- p7 e9 E' B6 f
    单的方法,将一个档案里的所有空白行删除。
    4 S7 y3 T( z/ e# q- Q3 rgawk 'BEGIN {for (i = 1; i <= 7; i++)& ?7 |7 x4 f; f, I5 @3 s
    print int(101 * rand())}'
    7 g' }# O$ u# [. F此程式会印出□围是 0 到 100 之间的 7 个乱数值。% R5 A, ~! @: U* K  B) V
    ls -l files | gawk '{x += $4}; END {print "total bytes: " x}'
    % s9 Q: i7 ^1 u/ |此程式会印出所有指定的档案之bytes数目的总和。
    ( n( S/ h: ]* O7 M, G) A$ \! l5 [expand file | gawk '{if (x < length()) x = length()}2 v$ K) A! M+ ?8 B0 \: T
    END {print "maximum line length is " x}'7 k# S' n7 I7 u+ |
    此程式会将指定档案里最长一行的长度印出。expand 会将 tab 改: I) ~( A  x: }" ^
    成 space,所以是用实际的右边界来做长度的比较。
    . W, u5 c7 n! Z+ ]0 Jgawk 'BEGIN {FS = ":"}
    " U) |/ S: T- D* _$ R+ B{print $1 | "sort"}' /etc/passwd
    1 C9 S+ Q5 D; D  g+ ?此程式会将所有使用者的login名称,依照字母的顺序印出。
      f8 T2 I: r, }; h- T; h6 P' v8 g9 ^gawk '{nlines++}
    9 ?" U* r4 l" r' r" z4 _8 s1 zEND {print nlines}'
    + j& D1 s( n) N5 G5 w此程式会将一个档案的总行数印出。, }( ]! }( c3 d- A
    gawk 'END {print NR}'
      c) B. i; ^- a9 F2 ~% ?此程式也会将一个档案的总行数印出,但是计算行数的工作由gawk2 [/ W0 x/ N& p2 K: R: b
    来做。! \: `8 s6 ~$ w' t# ^& F
    gawk '{print NR,$0}'
    6 U* W& F4 i  Q% C此程式印出档案的内容时,会在每行的最前面印出行号,它的功
    & f& }+ _3 j3 l5 L8 h能与 'cat -n' 类似。6 L" j+ x" h5 N6 _
    5 b& J8 o) N0 v% i. J* K2 X
    第十一章 结论
    . J4 X2 A" k: vgawk 对於资料的处理具有很强的功能。它能够以很短的程式完成
    2 V3 O/ ]1 h; c想要做的事,甚至一或二行的程式就能完成指定的工作。同样的一件
    ! {# e: q2 N3 `% A4 Q' d工作,以 gawk 程式来写会比用其它程式语言来写短很多。
      r- }0 i+ P3 ?& K, D! V5 fgawk 是 GNU 所做的 awk,它是公众软体(Public Domain) 可免费使
    4 ~& y1 F! Y" ~% \用。
    "真诚赞赏,手留余香"
    还没有人打赏,支持一下
    楼主热帖

    相关帖子

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

    该用户从未签到

    尚未签到

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

    本版积分规则

    招聘斑竹

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

    GMT+8, 2026-3-18 11:54

    Powered by Discuz! X3.5 Licensed

    © 2001-2025 Discuz! Team.

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