awk: 計算一欄數字的sum

用awk指令計算檔案中某一列的總和:
awk 'BEGIN{sum=0}{sum+=$1}END{print sum}' data.txt
比對完整的一個例子:
awk -F ',' 'BEGIN{sum=0 ;count=0}{if ($(NF-11) == 2 && $NF == 0 && $3 == "1.6.1_1_1") {sum +=$5; count++;} } END {print "sum="sum" count="count " avg="sum/count}'
說明:
BEGIN{sum=0 ;count=0} 起始化計數器;
END {print "sum="sum" count="count " avg="sum/count} 列印匯總,計數器 和均值;
if ($(NF-11) == 2 && $NF == 0 && $3 == "1.6.1_1_1") {sum +=$5; count++;} 判斷倒數第11個欄位,判斷倒數第一個欄位,判斷第三個欄位(字串) 第五個欄位匯總累加,計數器累加

很久以前看到gawk手冊:從很多電腦朮語的使用來看估計出處是台灣。
GAWK手冊
第一章 前言
第二章 簡介
第三章 讀取匯入檔案
第四章 印出
第五章 Patterns
第六章 算式(Expression)作為Actions的敘述
第七章 Actions裡面的控制敘述
第八章 內建函數(Built-in Functions)
第九章 使用者定義的函數
第十章 例子
第十一章 結論
======================================

第一章 前言
awk 是一個程式語言,對於資料的處理具有很強的功能。對於文字檔裡的資料做修改、
比對、抽取等的處理,awk 能夠以很短的程式輕易地完成。如果使用 C 或 Pascal 等
語言寫程式完成上述的動作,會不方便且很花費時間,所寫的程式也會很大。
awk 能夠依照使用者的定義格式來分解匯入資料,也可依照使用者定義的格式來印出資
料。
awk 名稱的由來是由它的初始設計者的姓氏之第一個字母而命名:Alfred V. Aho,
Peter J. Weinberger, Brian W. Kernighan。 awk最初在1977年完成。一個新版本的
awk在1985年被發表,它的功能比舊版本增強不少。
gawk 是GNU所做的 awk,gawk 最初在1986年完成,之後不斷地被改進、更新。gawk 包
含 awk 的所有功能。
往後的 gawk 將以下面的2個匯入檔案來做例子說明。
檔案'BBS-list': aardvark 555-5553 1200/300 B alpo-net 555-3412
2400/1200/300 A barfly 555-7685 1200/300 A bites 555-1675 2400/1200/300 A
camelot 555-0542 300 C core 555-2912 1200/300 C fooey 555-1234 2400/1200/300
B foot 555-6699 1200/300 B macfoo 555-6480 1200/300 A sdace 555-3430
2400/1200/300 A sabafoo 555-2127 1200/300 C
檔案'shipped': Jan 13 25 15 115 Feb 15 32 24 226 Mar 15 24 34 228 Apr 31 52
63 420 May 16 34 29 208 Jun 31 42 75 492 Jul 24 34 67 436 Aug 15 34 47 316
Sep 13 55 37 277 Oct 29 54 68 525 Nov 20 87 82 577 Dec 17 35 61 401
Jan 21 36 64 620 Feb 26 58 80 652 Mar 24 75 70 495 Apr 21 70 74 514
第二章 簡介
gawk 的主要功能是針對檔案的每一行(line)搜尋指定的 patterns 。當一行裡有符合
指定的 patterns,gawk 就會在此一行執行被指定的 actions。 gawk 依此方式處理輸
入檔案的每一行直到匯入檔案結束。
gawk 程式是由很多的 pattern 與 action 所組成,action 寫在大括弧 { } 裡面,一
個pattern後面就跟著一個action。整個 gawk 程式會像下面的樣子:
pattern {action} pattern {action}
在 gawk 程式裡面的規則,pattern 或 action 能夠被省略,但是兩個無法同時被省
略。如果 pattern 被省略,對於匯入檔裡面的每一行,action 都會被執行。如果
action 被省略,內定的 action 則會印出所有符合 pattern 的匯入行。
2.1 如何執行gawk程式
基本上,有2個方法可以執行gawk程式。
如果 gawk 程式很短,則 gawk 可以直接寫在 command line,如下所示:
gawk 'program' input-file1 input-file2 …
其中 program 包括一些 pattern 和 action。
如果 gawk 程式較長,較為方便的做法是將 gawk 程式存在一個檔案, 即 patterns
與 actions 寫在檔名為 program-file 的檔案裡面,執行 gawk 的格式如下所示:
gawk -f program-file input-file1 input-file2 …
gawk 程式的檔案不止一個時,執行gawk 的格式如下所示:
gawk -f program-file1 -f program-file2 … input-file1 input-file2 …
2.2 一個簡單的例子
現在我們舉一個簡單的例子,因為 gawk 程式很短,所以將 gawk 程式直接寫在
command line。
gawk '/foo/ {print $0}' BBS-list
實際的 gawk 程式為 /foo/ {print $0}。/foo/ 為 pattern,意思為搜尋匯入檔裡的
每一行是否含有子字串 'foo',如果含有 'foo' 則執行 action。 action 為 print
$0,是將現在這一行的內容印出。BBS-list 是匯入的檔案。
執行完上述指令後,會印出下面的結果: fooey 555-1234 2400/1200/300 B foot
555-6699 1200/300 B macfoo 555-6480 1200/300 A sabafoo 555-2127 1200/300 C
2.3 一個較複雜的例子
gawk '$1 == "Feb" {sum=$2+$3} END {print sum}' shipped
現在這個例子會將匯入檔 'shipped' 的第一個欄位與 "Feb" 做比對,如果相等,則其
對應的第2欄位與第3欄位的值會被加到變數 sum。對於匯入檔的每一行重複上述的動
作,直到匯入檔的每一行都被處理過為止。最後將 sum 的值印出。END {print sum}
的意思為在所有的匯入讀完之後,執行一次 print sum 的動作,也就是把 sum 的值印
出。
下面是執行的結果: 84
第三章 讀取匯入檔案
gawk的匯入可以從標准匯入或指定的檔案裡讀取。匯入的讀取單位被稱為”記錄”
(records),gawk 在做處理時,是一個記錄一個記錄地處理。每個記錄的內定值是一行
(line),一個記錄又被分為多個欄位(fields)。
3.1 如何將匯入分解成記錄(records)
gawk 語言會把匯入分解成記錄(record)。記錄與記錄之間是以 record separator 隔
開,record separator 的內定值是表示新一行的字元(newline character),因此內定
的 record separator 使得文字的每一行是一個記錄。
record separator 隨著內建變數 RS 的改變而改變。RS 是一個字串,它的內定值是
"\n"。僅有 RS 的第一個字元是有效的,它被當作 record separator,而 RS 的其他
字元會被舍棄。
內建變數 FNR 會儲存目前的匯入檔案已經被讀取的記錄之個數。內建變數 NR 會儲存
目前為止所有的匯入檔案已經被讀取的記錄之個數。
3.2 欄位(field)
gawk 會自動將每個記錄分解成多個欄位 (field)。類似於字在一行裡面,gawk 的內定
動作會認為欄位之間是以 whitespace 分開。在 gawk 裡,whitespace 的意思是一個
或多個空白或 tabs。
在 gawk 程式裡面,以'$1'表示第一個欄位,'$2'表示第二個欄位,依此類推。舉個例
子,假設匯入的一行如下所示:
This seems like a pretty nice example.
第一個欄位或 $1 是'This',第二個欄位或 $2 是 'seems',依此類推。有個地方值得
特別注意,第七個欄位或 $7 是'example.'而非'example'。
不論有多少欄位,$NF 可用來表示一個記錄的最後一個欄位。以上面的例子為例,$NF
與 $7 相同,也就是'example.'。
NF 是一個內建變數,它的值表示目前這個記錄之欄位的個數。
$0,看起來好像是第零個欄位,它是一個特例,它表示整個記錄。
下面是一個較複雜的例子:
gawk '$1~/foo/ {print $0}' BBS-list
結果如下: fooey 555-1234 2400/1200/300 B foot 555-6699 1200/300 B macfoo
555-6480 1200/300 A sabafoo 555-2127 1200/300 C
這個例子是把匯入檔'BBS-list'的每個記錄的第一個欄位作檢查,如果它含有子字串
'foo',則這一個記錄會被印出。
3.3 如何將記錄分解成欄位
gawk 根據 field separator 將一個記錄分解成欄位。field sepa- rator 以內建變數
FS 表示。
舉個例子,假如 field separator 是'oo',則下面的行:
moo goo gai pan
會被分成三個欄位:'m'、' g'、' gai pan'。
在 gawk 程式裡,可以使用'='來改變 FS 的值。例如:
gawk 'BEGIN {FS=","}; {print $2}'
匯入行如下:
John Q. Smith, 29 Oak St., Walamazoo, MI 42139
執行gawk的結果將印出字串 ' 29 Oak St.'。BEGIN 後面的 action 會在第一個記錄被
讀取之前執行一次。
第四章 印出
在gawk程式裡,actions 最常做的事就是印出(printing)。簡單的印出,使用 printe
敘述。複雜格式的印出,使用 printf 敘述。
4.1 print敘述
print 敘述用在簡單、標准的匯出格式。敘述的格式如下所示:
print item1, item2, …
匯出時,各個 item 之間會以一個空白分開,最後會換行(newline)。
如果 'print'敘述之後沒有跟著任何東西,它與'print $0'的效果一樣,它會印出現在
的記錄(record)。要印出空白行可使用'print ""'。 印出一段固定的文字,可用雙引
號將文字的兩邊括起來,例如 'print "Hello there"'。
這裡是一個例子,它會把每個匯入記錄的前二個欄位印出:
gawk '{print $1,$2}' shipped
結果如下所示: Jan 13 Feb 15 Mar 15 Apr 31 May 16 Jun 31 Jul 24 Aug 15 Sep
13 Oct 29 Nov 20 Dec 17
Jan 21 Feb 26 Mar 24 Apr 21
4.2 Output Separators
前面我們已提過如果 print 敘述包含有多個 item,item 之間用逗點分開,則印出時
各個item會被一個空白隔開。你能夠使用任何的字串作為 output field separator,
可以經由內建變數 OFS 的設定來變更 output field separator。OFS 的初始值為"
",即一格的空白。
整個 print 敘述的匯出被稱為 output record。print 敘述匯出 output record 之
後,會接著匯出一個字串,此字串稱為 output record separator。內建變數 ORS 用
來指明此字串。ORS 的初始值為 "\n",也就是換行。
下面這個例子會印出每個記錄的第一個欄位和第二個欄位,此二個欄位之間以分號';'
分開,每行匯出之後會加入一個空白行。
gawk 'BEGIN {OFS=";"; ORS="\n\n"} {print $1, $2}' BBS-list
結果如下所示: aardvark;555-5553
alpo-net;555-3412
barfly;555-7685
bites;555-1675
camelot;555-0542
core;555-2912
fooey;555-1234
foot;555-6699
macfoo;555-6480
sdace;555-3430
sabafoo;555-2127
4.3 printf敘述
printf 敘述會使得匯出格式較容易精確地控制。printf 敘述可以指定每個 item 印出
的寬度,也可以指定數字的各種型式。
printf 敘述的格式如下:
printf format, item1, item2, …
print 與 printf 的差別是在於 format, printf 的引數比 print 多了字串 format。
format 的型式與 ANSI C 的 printf 之格式相同。
printf 并不會做自動換行的動作。內建變數 OFS 與 ORS 對 printf 敘述沒有任何影
響。
格式的指定以字元'%'開始,後面接著格式控制字母。
格式控制字母如下所示:
'c' 將數字以 ASCII 字元印出。 例如'printf "%C",65'會印出字元'A'。
'd' 印出十進位的整數。
'i' 印出十進位的整數。
'e' 將數字以科學象徵式的形式印出。 例如
print "$4.3e",1950
結果會印出'1.950e+03'。
'f' 將數字以浮點的形式印出。
'g' 將數字以科學象徵式的形式或浮點的形式印出。數字的絕對值如果 大於等於0.0001
則以浮點的形式印出,否則以科學象徵式的形式印 出。
'o' 印出無號的八進位整數。
's' 印出一個字串。
'x' 印出無號的十六進位整數。10至15以'a'至'f'表示。
'X' 印出無號的十六進位整數。10至15以'A'至'F"表示。
'%' 它并不是真正的格式控制字母,'%%"將印出"%'。
在 % 與格式控制字母之間可加入 modifier,modifier 是用來進一步控制匯出的格
式。可能的 modifier 如下所示:
'-' 使用在 width 之前,指明是向左靠齊。如果'-'沒有出現,則會在 被指定的寬度
向右靠齊。例如:
printf "%-4S", "foo"
會印出'foo '。
'width' 這一個數字指示相對應的欄位印出時的寬度。例如:
printf "%4s","foo"
會印出' foo'。
width 的值是一個最小寬度而非最大寬度。如果一個 item 的 值需要的寬度比 width
大,則不受 width 的影響。例如
printf "%4s","foobar"
將印出'foobar'。
'.prec' 此數字指定印出時的精確度。它指定小數點右邊的位數。如 果是要印出一個
字串,它指定此字串最多會被印出多少個位元組。
第五章 patterns
在 gawk 程式裡面,當 pattern 符合現在的匯入記錄(record),其相對應的 action
才會被執行。
5.1 Pattern的種類
這裡對 gawk 的各種 pattern 型式作一整理:
/regular expression/ 一個 regular expression 當作一個 pattern。每當匯入記錄
( record)含有 regular expression 就視為符合。
expression 一個單一的 expression。當一個值不為 0 或一個字串不是空的, 則可視
為符合。
pat1,pat2 一對的 patterns 以逗點分開,指定記錄的範圍。
BEGIN END 這是特別的 pattern, gawk 在開始執行或要結束時會分別執行相 對應於
BEGIN或END的 action。
null 這是一個空的pattern,對於每個匯入記錄皆視為符合pattern。
5.2 Regular Expressions當作Patterns
一個 regular expression 可簡寫為 regexp,是一種說明字串的方法。一個 regular
expression 以斜線('/')包圍當作 gawk 的 pattern。
如果匯入記錄含有 regexp 就視為符合。例如:pattern 為 /foo/,對於任何匯入記錄
含有'foo'則視為符合。
下面的例子會將含有'foo'的匯入記錄之第2個欄位印出。
gawk '/foo/ {print $2}' BBS-list
結果如下: 555-1234 555-6699 555-6480 555-2127
regexp 也能使用在比對的算式。
exp ~ /regexp/ 如果 exp 符合 regexp,則結果為真(true)。
exp !~ /regexp/ 如果 exp 不符合 regexp,則結果為真。
5.3 比對的算式當作Patterns
比對的 pattern 用來測試兩個數字或字串的關係諸如大於、等於、小於。下面列出一
些比對的pattern:
x
如果 x 大於 y,則結果為真。 x>=y 如果 x 大於、等於 y,則結果為真。 x==y 如果
x 等於 y,則結果為真。 x!=y 如果 x 不等於 y,則結果為真。 x~y 如果 x 符合
regular expression y,則結果為真。 x!~y 如果 x 不符合 regular expression y,
則結果為真。
上面所提到的 x 與 y,如果二者皆是數字則視為數字之間的比對,否則它們會被轉換
成字串且以字串的形式做比對。兩個字串的比對,會先比對第一個字元,然後比對第二
個字元,依此類推,直到有不同的地方出現為止。如果兩個字串在較短的一個結束之前
是相等,則視為長的字串比短的字串大。例如 "10" 比 "9" 小,"abc" 比 "abcd"
小。
5.4 使用布林運算的Patterns
一個布林(boolean) pattern 是使用布林運算"或"('||'),"及" ('&&'),"反"('!')來
組合其他的pattern。例如:
gawk '/2400/ && /foo/' BBS-list gawk '/2400/ || /foo/' BBS-list gawk '!
/foo/' BBS-list
第六章 算式(Expression)作為Actions的敘述
算式(Expression) 是gawk程式裡面action的基本搆成者。
6.1 算朮運算
gawk 裡的算朮運算如下所示:
x+y 加 x-y 減 -x 負 +x 正。實際上沒有任何影響。 x*y 乘 x/y 除 x%y 求余數。例
如 5%3=2。 x^y x**y x 的 y 次方。例如2^3=8。
6.2 比對算式與布林算式
比對算式 (comparison expression) 用來比對字串或數字的關係,運算子號與 C 語言
相同。表列如下:
x
比對的結果為真(true)則其值是 1。否則其值是 0。
布林算式(boolean expression)有下面三種:
boolean1 && boolean2 boolean1 || boolean2 ! boolean
6.3 條件算式(Conditional Expressions)
一個條件式算式是一種特別的算式,它含有3個運算元。 條件式算式與C語言的相同:
selector ? if-true-exp : if-false-exp
它有3個子算式。第一個子算式selector 首先會被計算。如果是真, 則if-true-exp會
被計算且它的值變成整個算式的值。否則if-false- exp 會被計算且它的值變成整個算
式的值。
例如下面的例子會產生x的絕對值:
x>0 ? x : -x
第七章 Actions裡面的控制敘述
在 gawk 程式裡面,控制敘述諸如 if、while 等控制程式執行的流程。在 gawk 裡的
控制敘述與 C 的類似。
很多的控制敘述會包括其他的敘述,被包括的敘述稱為 body。假如 body 裡面包括一
個以上的敘述,必須以大括弧 { } 將這些敘述括起來,而各個敘述之間需以換行
(newline)或分號隔開。
7.1 if 敘述
if (condition) then-body [else else-body]
如果 condition 為真(true),則執行 then-body,否則執行 else-body。
舉一個例子如下:
if (x % 2 == 0) print "x is even" else print "x is odd"
7.2 while 敘述
while (condition) body
while 敘述做的第一件事就是測試 condition。假如 condition 為真則執行 body 的
敘述。body 的敘述執行完後,會再測試 condition,假如 condition 為真,則 body
會再度被執行。這個過程會一直被重複直到 condition 不再是真。如果 condition 第
一次測試就是虛擬(false),則 body 從沒有被執行。
下面的例子會印出每個匯入記錄(record)的前三個欄位。
gawk '{ i=1 while (i <= 3) { print $i i++ } }'
7.3 do-while 敘述
do body while (condition)
這個 do loop 執行 body 一次,然後只要 condition 是真則會重複執行 body。即使
開始時 condition 是虛擬,body 也會被執行一次。
下面的例子會印出每個匯入記錄十次。
gawk '{ i= 1 do { print $0 i++ } while (i <= 10) }'
7.4 for 敘述
for (initialization; condition; increment) body
此敘述開始時會執行initialization,然後只要 condition是真,它會重複執行body與
做increment 。
下面的例子會印出每個匯入記錄的前三個欄位。
gawk '{ for (i=1; i<=3; i++) print $i }'
7.5 break 敘述
break 敘述會跳出包含它的 for、while、do-while 回圈的最內層。
下面的例子會找出任何整數的最小除數,它也會判斷是否為質數。
gawk '# find smallest divisor of num { num=$1 for (div=2; div*div <=num;
div++) if (num % div == 0) break if (num % div == 0) printf "Smallest
divisor of %d is %d\n", num, div else printf "%d is prime\n", num }'
7.6 continue 敘述
continue 敘述使用於 for、while、do-while 回圈內部,它會略過回圈 body 的剩余
部分,使得它立刻進行下一次回圈的執行。
下面的例子會印出 0 至 20 的全部數字,但是 5 并不會被印出。
gawk 'BEGIN { for (x=0; x<=20; x++) { if (x==5) continue printf ("%d",x) }
print "" }'
7.7 next 敘述、next file 敘述、exit 敘述
next 敘述強迫 gawk 立刻停止處理目前的記錄(record)而繼續下一個記錄。
next file 敘述類似 next。然而,它強迫 gawk 立刻停止處理目前的資料檔。
exit 敘述會使得 gawk 程式停止執行而跳出。然而,如果 END 出現,它會去執行 END
的 actions。
第八章 內建函數(Built-in Functions)
內建函數是 gawk 內建的函數,可在 gawk 程式的任何地方呼叫內建函數。
8.1 數值方面的內建函數
int(x) 求出 x 的整數部份,朝向 0 的方向做舍去。例如:int(3.9) 是 3,
int(-3.9) 是 -3。 sqrt(x) 求出 x 正的平方根值。例 sqrt(4)=2 exp(x) 求出 x 的
次方。例 exp(2) 即是求 e*e 。 log(x) 求出 x 的自然對數。 sin(x) 求出 x 的
sine 值,x 是弳度量。 cos(x) 求出 x 的 cosine 值,x 是弳度量。 atan2(y,x) 求
y/x 的 arctangent 值,所求出的值其單位是弳度量。 rand() 得出一個亂數值。此亂
數值平均分散在 0 和 1 之間。這個 值不會是 0,也不會是 1。 每次執行 gawk,
rand 開始產生數字從相同點或 seed。 srand(x) 設定產生亂數的開始點或 seed 為
x。如果在第二次你設 定相同的 seed 值,你將再度得到相同串列的亂數值。 如果省
略引數 x,例如 srand(),則現在的日期、時間會 被當成 seed。這個方法可使得亂數
值是真正不可預測的。 srand 的傳回值(return value)是前次所設定的 seed 值。
8.2 字串方面的內建函數
index(in, find) 它會在字串 in 裡面,搜尋字串 find 第一次出現的地方,傳回值是
字串 find 出現在字串 in 裡面的位置。如果在字串 in 裡面找不到字 串 find,則傳
回值為 0。 例如: print index("peanut","an") 會印出 3。
length(string) 求出 string 有几個字元。 例如: length("abcde") 是 5。
match(string,regexp) match 函數會在字串 string 裡面,搜尋符合 regexp 的最
長、最靠 左邊的子字串。傳回值是 regexp 在 string 的開始位置,即 index 值。
match 函數會設定內在變數 RSTART 等於 index,它也會設定內在變 數 RLENGTH 等於
符合的字元個數。如果不符合,則會設定 RSTART 為 0、RLENGTH 為 -1。
sprintf(format,expression1,…) 舉 printf 類似,但是 sprintf 并不印出,而是
傳回字串。 例如: sprintf("pi = %.2f (approx.)',22/7) 傳回的字串為"pi = 3.14
(approx.)"
sub(regexp, replacement,target) 在字串 target 裡面,搜尋符合 regexp 的最長、
最靠左邊的地方, 以字串 replacement 代替最左邊的 regexp。 例如: str =
"water, water, everywhere" sub(/at/, "ith",str) 結果字串str會變成 "wither,
water, everywhere"
gsub(regexp, replacement, target) gsub 與前面的 sub 類似。在字串 target 裡
面,搜尋符合 regexp 的 所有地方,以字串 replacement 代替所有的 regexp。 例如
: str="water, water, everywhere" gsub(/at/, "ith",str) 結果字串str會變成
'wither, wither, everywhere"
substr(string, start, length) 傳回字串 string 的子字串,這個子字串的長度為
length 個字元, 從第 start 個位置開始。 例如: substr("washington",5,3) 傳回
值為"ing" 如果 length 沒有出現,則傳回的子字串是從第 start 個位置開始 至結
束。 例如: substr("washington",5) 傳回值為"ington"
tolower(string) 將字串string的大寫字母改為小寫字母。 例如: tolower("MiXeD
cAsE 123") 傳回值為"mixed case 123"
toupper(string) 將字串string的小寫字母改為大寫字母。 例如: toupper("MiXeD
cAsE 123") 傳回值為"MIXED CASE 123"
8.3 匯入匯出的內建函數
close(filename) 將匯入或匯出的檔案 filename 關閉。
system(command) 此函數允許使用者執行作業系統的指令,執行完畢後將回到 gawk 程
式。 例如: BEGIN {system("ls")}
第九章 使用者定義的函數(User-defined Functions)
複雜的 gawk 程式常常可以使用自己定義的函數來簡化。呼叫使用者定義的函數與呼叫
內建函數的方法一樣。
9.1 函數定義的格式
函數的定義可以放在 gawk 程式的任何地方。
一個使用者定義的函數其格式如下:
function name (parameter-list) { body-of-function }
name 是所定義的函數之名稱。一個正確的函數名稱可包括一串列的字母、數字、下標
線 (underscores),但是不可用數字做開頭。
parameter-list 是列出函數的全部引數(argument),各個引數之間以逗點隔開。
body-of-function 包含 gawk 的敘述 (statement)。它是函數定義裡最重要的部份,
它決定函數實際要做何種事。
9.2 函數定義的例子
下面這個例子,會將每個記錄的第一個欄位之值的平方與第二個欄位之值的平方加起
來。
{print "sum =",SquareSum($1,$2)} function SquareSum(x,y) { sum=x*x+y*y
return sum }
第十章 例子
這裡將列出 gawk 程式的一些例子。
gawk '{if (NF > max) max = NF} END {print max}' 此程式會印出所有匯入行之中,
欄位的最大個數。
gawk 'length($0) > 80' 此程式會印出一行超過 80 個字元的每一行。此處只有
pattern 被 列出,action 是釆用內定的 print。
gawk 'NF > 0' 對於擁有至少一個欄位的所有行,此程式皆會印出。這是一個簡 單的
方法,將一個檔案裡的所有空白行移除。
gawk '{if (NF > 0) print}' 對於擁有至少一個欄位的所有行,此程式皆會印出。這
是一個簡 單的方法,將一個檔案裡的所有空白行移除。
gawk 'BEGIN {for (i = 1; i <= 7; i++) print int(101 * rand())}' 此程式會印出
範圍是 0 到 100 之間的 7 個亂數值。
ls -l files | gawk '{x += $4}; END {print "total bytes: " x}' 此程式會印出所
有指定的檔案之bytes數目的總和。
expand file | gawk '{if (x < length()) x = length()} END {print "maximum
line length is " x}' 此程式會將指定檔案裡最長一行的長度印出。expand 會將 tab
改 成 space,所以是用實際的右邊線來做長度的比對。
gawk 'BEGIN {FS = ":"} {print $1 | "sort"}' /etc/passwd 此程式會將所有使用者
的login名稱,依照字母的順序印出。
gawk '{nlines++} END {print nlines}' 此程式會將一個檔案的總行數印出。
gawk 'END {print NR}' 此程式也會將一個檔案的總行數印出,但是計算行數的工作由
gawk 來做。
gawk '{print NR,$0}' 此程式印出檔案的內容時,會在每行的最前面印出行號,它的
功 能與 'cat -n' 類似。
第十一章 結論
gawk 對於資料的處理具有很強的功能。它能夠以很短的程式完成想要做的事,甚至一
或二行的程式就能完成指定的工作。同樣的一件工作,以 gawk 程式來寫會比用其他程
式語言來寫短很多。
gawk 是 GNU 所做的 awk,它是公眾軟體(Public Domain) 可免費使用。
作者:车东 發表於:2005-03-11 16:03 最后更新於:2007-04-15 19:04
版权声明:可以任意轉載,轉載時請務必以超鏈結形式標明文章原始出处和作者資訊及本版权声明。
http://www.chedong.com/blog/archives/000682.html