歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網

awk

日期:2017/3/6 15:25:36   编辑:關於Unix
studying... a w k是一種程序語言,對文檔資料的處理具有很強的功能。awk 名稱是由它三個最初設計 者的姓氏的第一個字母而命名的: Alfred V. Aho、Peter J. We i n b e rg e r、Brian W. Kernighan。 a w k最初在1 9 7 7年完成。1 9 8 5年發表了一個新版本的 studying...

a w k是一種程序語言,對文檔資料的處理具有很強的功能。awk 名稱是由它三個最初設計
者的姓氏的第一個字母而命名的: Alfred V. Aho、Peter J. We i n b e rg e r、Brian W. Kernighan。
a w k最初在1 9 7 7年完成。1 9 8 5年發表了一個新版本的a w k,它的功能比舊版本增強了不少。a w k
能夠用很短的程序對文檔裡的資料做修改、比較、提取、打印等處理。如果使用C 或P a s c a l
等語言編寫程序完成上述的任務會十分不方便而且很花費時間,所寫的程序也會很大。
a w k不僅僅是一個編程語言,它還是L i n u x系統管理員和程序員的一個不可缺少的工具。
a w k語言本身十分好學,易於掌握,並且特別的靈活。
gawk 是G N U計劃下所做的a w k,gawk 最初在1 9 8 6年完成,之後不斷地被改進、更新。
gawk 包含awk 的所有功能。

6.1 gawk的主要功能
gawk 的主要功能是針對文件的每一行( l i n e ),也就是每一條記錄,搜尋指定的格式。當某
一行符合指定的格式時,gawk 就會在此行執行被指定的動作。gawk 依此方式自動處理輸入文
件的每一行直到輸入文件檔案結束。
g a w k經常用在如下的幾個方面:
• 根據要求選擇文件的某幾行,幾列或部分字段以供顯示輸出。
• 分析文檔中的某一個字出現的頻率、位置等。
• 根據某一個文檔的信息准備格式化輸出。
• 以一個功能十分強大的方式過濾輸出文檔。
• 根據文檔中的數值進行計算。

6.2 如何執行gawk程序
基本上有兩種方法可以執行g a w k程序。
如果gawk 程序很短,則可以將gawk 直接寫在命令行,如下所示:
gawk 'program' input-file1 input-file2 ...
其中program 包括一些pattern 和a c t i o n。
如果gawk 程序較長,較為方便的做法是將gawk 程序存在一個文件中,
gawk 的格式如下所示:
gawk -f program-file input-file1 input-file2 ...
gawk 程序的文件不止一個時,執行gawk 的格式如下所示:
gawk -f program-file1 -f program-file2 ... input-file1 input-file2 ...

6.3 文件、記錄和字段
一般情況下,g a w k可以處理文件中的數值數據,但也可以處理字符串信息。如果數據沒有
存儲在文件中,可以通過管道命令和其他的重定向方法給g a w k提供輸入。當然, g a w k只能處
理文本文件(A S C I I碼文件)。

電話號碼本就是一個g a w k可以處理的文件的簡單例子。電話號碼本由很多條目組成,每一
個條目都有同樣的格式:姓、名、地址、電話號碼。每一個條目都是按字母順序排列。
在g a w k中,每一個這樣的條目叫做一個記錄。它是一個完整的數據的集合。例如,電話號
碼本中的Smith John這個條目,包括他的地址和電話號碼,就是一條記錄。
記錄中的每一項叫做一個字段。在g a w k中,字段是最基本的單位。多個記錄的集合組成了
一個文件。
大多數情況下,字段之間由一個特殊的字符分開,像空格、TA B、分號等。這些字符叫做
字段分隔符。請看下面這個/ e t c / p a s s w d文件:
t p a r k e r ; t 3 6 s 6 2 h s h ; 5 0 1 ; 1 0 1 ; Tim Parker;/home/tparker;/bin/bash
etreijs;2ys639dj3h;502;101;Ed Tr e i j s ; / h o m e / e t r e i j s ; / b i n / t c s h
y c h o w ; 1 h 2 7 s j ; 5 0 3 ; 1 0 1 ; Yvonne Chow;/home/ychow;/bin/bash
你可以看出/ e t c / p a s s w d文件使用分號作為字段分隔符。/ e t c / p a s s w d文件中的每一行都包括
七個字段:用戶名;口令;用戶I D;工作組I D;注釋; h o m e目錄;啟始的外殼。如果你想要
查找第六個字段,只需數過五個分號即可。
但考慮到以下電話號碼本的例子,你就會發現一些問題:
Smith John 13 Wilson St. 555-1283
Smith John 2736 Artside Dr Apt 123 555-2736
Smith John 125 Westmount Cr 555-1726
雖然我們能夠分辨出每個記錄包括四個字段,但g a w k卻無能為力。電話號碼本使用空格作
為分隔符,所以g a w k認為S m i t h是第一個字段, John 是第二個字段,1 3是第三個字段,依次類
推。就g a w k而言,如果用空格作為字段分隔符的話,則第一個記錄有六個字段,而第二個記
錄有八個字段。
所以,我們必須找出一個更好的字段分隔符。例如,像下面一樣使用斜槓作為字段分隔
符:
Smith/John/13 Wilson St./555-1283
Smith/John/2736 Artside Dr/Apt/123/555-2736
Smith/John/125 Westmount Cr/555-1726
如果你沒有指定其他的字符作為字段分隔符,那麼g a w k將缺省地使用空格或TA B作為字段
分隔符。

6.4 模式和動作
在g a w k語言中每一個命令都由兩部分組成:一個模式( p a t t e r n)和一個相應的動作
(a c t i o n)。只要模式符合,g a w k就會執行相應的動作。其中模式部分用兩個斜槓括起來,而動
作部分用一對花括號括起來。例如:
/ p a t t e r n 1 / { a c t i o n 1 }
/ p a t t e r n 2 / { a c t i o n 2 }
/ p a t t e r n 3 / { a c t i o n 3 }
所有的g a w k程序都是由這樣的一對對的模式和動作組成的。其中模式或動作都能夠被省
略,但是兩個不能同時被省略。如果模式被省略,則對於作為輸入的文件裡面的每一行,動作
都會被執行。如果動作被省略,則缺省的動作被執行,既顯示出所有符合模式的輸入行而不做
任何的改動。
下面是一個簡單的例子,因為gawk 程序很短,所以將gawk 程序直接寫在外殼命令行:
gawk '/tparker/' /etc/passwd
此程序在上面提到的/ e t c / p a s s w d文件中尋找符合t p a r k e r模式的記錄並顯示(此例中沒有動
作,所以缺省的動作被執行)。
讓我們再看一個例子:
gawk '/UNIX/{print }' file2.data
此命令將逐行查找f i l e 2 . d a t a文件中包含U N I X的記錄,並打印這些記錄的第二個字段。
你也可以在一個命令中使用多個模式和動作對,例如:
gawk '/scandal/{print } /rumor/{print }' gossip_file
此命令搜索文件g o s s i p _ f i l e中包括s c a n d a l的記錄,並打印第一個字段。然後再從頭搜索
g o s s i p _ f i l e中包括r u m o r的記錄,並打印第二個字段。

6.5 比較運算和數值運算
g a w k有很多比較運算符,下面列出重要的幾個:
= = 相等
! = 不相等
> 大於
< 小於
> = 大於等於
< = 小於等於
例如:
gawk ' > 100' testfile
將會顯示文件testfile 中那些第四個字段大於1 0 0的記錄。
下表列出了g a w k中基本的數值運算符。
運算符說明示例
+ 加法運算2+6
- 減法運算6-3
* 乘法運算2*5
/ 除法運算8/4
^ 乘方運算3^2 (=9)
% 求余數9%4 (=1)
例如:
{print /2}
顯示第三個字段被2除的結果。
在g a w k中,運算符的優先權和一般的數學運算的優先權一樣。例如:
{print +*}
顯示第二個字段和第三個字段相乘,然後和第一個字段相加的結果。
你也可以用括號改變優先次序。例如:
{print (+)*}
顯示第一個字段和第二個字段相加,然後和第三個字段相乘的結果。

6.6 內部函數

g a w k中有各種的內部函數,現在介紹如下:

6.6.1 隨機數和數學函數
sqrt(x) 求x 的平方根
sin(x) 求x 的正弦函數
cos(x) 求x 的余弦函數
a t a n 2 ( x,y) 求x / y的余切函數
log(x) 求x 的自然對數
exp(x) 求x 的e 次方
int(x) 求x 的整數部分
rand() 求0 和1之間的隨機數
srand(x) 將x 設置為r a n d ( )的種子數

6.6.2 字符串的內部函數
• i n d e x ( i n,find) 在字符串in 中尋找字符串find 第一次出現的地方,返回值是字符串
find 出現在字符串in 裡面的位置。如果在字符串in 裡面找不到字符串f i n d,則返回值為
0。
例如:
print index("peanut"," a n " )
顯示結果3。
• length(string) 求出string 有幾個字符。
例如:
l e n g t h ( " a b c d e " )
顯示結果5。
• m a t c h ( s t r i n g,r e g e x p ) 在字符串string 中尋找符合regexp 的最長、最靠左邊的子字
符串。返回值是regexp 在string 的開始位置,即i n d e x值。match 函數將會設置系統變量
R S TA RT 等於i n d e x的值,系統變量RLENGTH 等於符合的字符個數。如果不符合,則會
設置R S TA RT 為0、RLENGTH 為- 1。
• s p r i n t f ( f o r m a t,e x p r e s s i o n 1,. . . ) 和printf 類似,但是sprintf 並不顯示,而是返回字符
串。
例如:
sprintf("pi = %.2f (approx.)",2 2 / 7 )
返回的字符串為pi = 3.14 (approx.)
• s u b ( r e g e x p,r e p l a c e m e n t,t a rg e t ) 在字符串t a rget 中尋找符合regexp 的最長、最靠左的
地方,以字串replacement 代替最左邊的r e g e x p。
例如:
str = "water,w a t e r,e v e r y w h e r e "
s u b ( / a t /, " i t h ",s t r )
結果字符串s t r會變成
w i t h e r,w a t e r,e v e r y w h e r e
• g s u b ( r e g e x p,r e p l a c e m e n t,t a rget) 與前面的s u b類似。在字符串t a rget 中尋找符合
r e g e x p的所有地方,以字符串replacement 代替所有的r e g e x p。
例如:
s t r = " w a t e r,w a t e r,e v e r y w h e r e "g s u b ( / a t /, " i t h ",s t r )
結果字符串s t r會變成
w i t h e r,w i t h e r,e v e r y w h e r e
• s u b s t r ( s t r i n g,s t a r t,length) 返回字符串string 的子字符串,這個子字符串的長度為
l e n g t h,從第start 個位置開始。
例如:
s u b s t r ( " w a s h i n g t o n ",5,3 )
返回值為i n g
如果沒有length ,則返回的子字符串是從第start 個位置開始至結束。
例如:
s u b s t r ( " w a s h i n g t o n ",5 )
返回值為i n g t o n。
• tolower(string) 將字符串s t r i n g的大寫字母改為小寫字母。
例如:
tolower("MiXeD cAsE 123")
返回值為mixed case 123。
• toupper(string) 將字符串s t r i n g的小寫字母改為大寫字母。
例如:
toupper("MiXeD cAsE 123")
返回值為MIXED CASE 123。

6.6.3 輸入輸出的內部函數
• close(filename) 將輸入或輸出的文件filename 關閉。
• system(command) 此函數允許用戶執行操作系統的指令,執行完畢後將回到g a w k程
序。
例如:
BEGIN

6.7 字符串和數字
字符串就是一連串的字符,它可以被g a w k逐字地翻譯。字符串用雙引號括起來。數字不能
用雙引號括起來,並且g a w k將它當作一個數值。例如:
gawk ' != "Tim" ' testfile
此命令將顯示第一個字段和Ti m不相同的所有記錄。如果命令中Ti m兩邊不用雙引號,
g a w k將不能正確執行。
再如:
gawk ' == "50" ' testfile
此命令將顯示所有第一個字段和5 0這個字符串相同的記錄。g a w k不管第一字段中的數值
的大小,而只是逐字地比較。這時,字符串5 0和數值5 0並不相等。

6.8 格式化輸出
我們可以讓動作顯示一些比較復雜的結果。例如:
gawk ' != "Tim" {print ,$ 5,$ 6,}' testfile
將顯示t e s t f i l e文件中所有第一個字段和Ti m不相同的記錄的第一、第五、第六和第二個字
段。
進一步,你可以在p r i n t動作中加入字符串,例如:
gawk ' != "Tim" {print "The entry for ",$ 1,"is not Tim. ",}' testfile
p r i n t動作的每一部分用逗號隔開。
借用C語言的格式化輸出指令,可以讓g a w k的輸出形式更為多樣。這時,應該用p r i n t f而不
是p r i n t。例如:
{printf "%5s likes this language\n",$ 2 }
p r i n t f中的%5s 部分告訴gawk 如何格式化輸出字符串,也就是輸出5個字符長。它的值由
printf 的最後部分指出,在此是第二個字段。\ n是回車換行符。如果第二個字段中存儲的是人
名,則輸出結果大致如下:
Tim likes this language
G e o ff likes this language
Mike likes this language
Joe likes this language
gawk 語言支持的其他格式控制符號如下:
• c 如果是字符串,則顯示第一個字符;如果是整數,則將數字以ASCII 字符的形式顯示。
例如:
printf “% c”,6 5
結果將顯示字母A。
• d 顯示十進制的整數。
• i 顯示十進制的整數。
• e 將浮點數以科學記數法的形式顯示。
例如:
print “$ 4 . 3 e”,1 9 5 0
結果將顯示1 . 9 5 0 e + 0 3。
• f 將數字以浮點的形式顯示。
• g 將數字以科學記數法的形式或浮點的形式顯示。數字的絕對值如果大於等於0 . 0 0 0 1則
以浮點的形式顯示,否則以科學記數法的形式顯示。
• o 顯示無符號的八進制整數。
• s 顯示一個字符串。
• x 顯示無符號的十六進制整數。1 0至1 5以a至f表示。
• X 顯示無符號的十六進制整數。1 0至1 5以A至F表示。
• % 它並不是真正的格式控制字符,% %將顯示%。
當你使用這些格式控制字符時,你可以在控制字符前給出數字,以表示你將用的幾位或幾
個字符。例如,6 d表示一個整數有6位。再請看下面的例子:
{printf "%5s works for %5s and earns %2d an hour",$ 1,$ 2,$ 3 }
將會產生類似如下的輸出:
Joe works for Mike and earns 12 an hour
當處理數據時,你可以指定數據的精確位數
{printf "%5s earns $%.2f an hour",$ 3,$ 6 }
其輸出將類似於:
Joe earns .17 an hour
你也可以使用一些換碼控制符格式化整行的輸出。之所以叫做換碼控制符,是因為g a w k對
這些符號有特殊的解釋。下面列出常用的換碼控制符:
\a 警告或響鈴字符。
\b 後退一格。
\f 換頁。
\n 換行。
\r 回車。
\t Ta b。
\v 垂直的t a b。

Copyright © Linux教程網 All Rights Reserved