歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Unix知識 >> 關於Unix >> Unix AWK 總結

Unix AWK 總結

日期:2017/2/28 11:26:33   编辑:關於Unix


  如果你不是很熟悉UNIX的話,你可能對Awk會有些陌生,的確,AWK作為一種優良的文本處理工具還沒有達到它應有的普及程度。但是它卻得到了熟悉並經常使用它的人們的一致稱贊。
  AWK到底是什麼?從字面上看,“AWK”這三個字母幾乎不能給我們任何提示,他不象一些UNIX命令一樣多多少少反映出了一些功能,如FIND和KILL一樣,也不象另一些UNIX命令是功能的簡寫,如l是list(列表)的縮寫,這些都能給我們多多少少一點提示,但awk不行. 事實上,AWK是三個程序大師首字符的縮寫,這三個人分別是:Aho、(Peter)Weinberg和(Brain)Kernighan。正是這三個人創造了AWK。顯然,這樣的詞匯組成形式不能給我們提供任何的幫助。
  那麼:AWK的功能到底是什麼呢?實際上AWK是一種文本文件處理工具,這一點與sed和grep很相似,但awk所提供的功能卻是sed和grep所無法望其項背的。awk提供了極其強大的功能:可以進行樣式裝入、流控制、數學運算符、進程控制語句甚至於內置的變量和函數。它具備了一個完整的語言所應具有的幾乎所有精美特性。實際上awk的確擁有自己的語言:awk程序設計語言,awk的三位創建者已將它正式定義為“樣式掃描和處理語言”。
  即使如此,你也許還要問:我為什麼要用awk?的確,unix擁有很多優秀的工具,便如C語言就是一種功能強大的武器,我們又為什麼要選擇awk呢?這首先是因為awk是一個容易得到的工具:幾乎每個UNIX系統都帶有自己的awk,而C語言卻是UNIX開發系統的一部分,如果你沒有安裝UNIX開發系統的話,你就不可能得到C語言。其次,awk是一個使用簡單的工具,有些問題也許C語言可以解決,但你卻不得不通過寫源程序、調試、編譯等等繁瑣的步驟,而awk就根本不存在這個問題。最後,awk在實現某些功能方面,的確是比C語言更為便捷的工具,而這些卻是更簡單一些的工具例如shell和處理文件所無法實現的。例如我曾經試圖用shell script寫一個實現銷售清單上銷售金額的累加,然而shell只提供了整數型的數據變量,對於小數點後面的兩位就無能為力了,而為了一個臨時性的工作專門寫一個C程序似乎又不值得,最後我想到了awk,結果非常輕松的實現了,也正是從那時起,我開始喜歡上awk了。在這裡有一個可遵循的一般原則:如果你用普通的shell工具或shell script有困難的話,試試awk,如果awk仍不能解決問題,則便用C語言,如果C語言仍然失敗,則移至C++。看了對awk的簡要介紹,你也許對awk有學習和掌握的願望了,既然如此,就讓我們開始探索awk的新旅程吧!
一、awk的語法。
awk是以unix的一個命令的形式提供給用戶的,你可以在/bin目錄下找到awk這個文
件,如果缺少這個文件,你就不能運行awk。因此,awk擁有自己的調用語法:
awk [ -F re][parameter...]['prog'][-f progfile][in_file...]
參數說明:
re awk記錄分隔符。
parameter 該參數幫助為不同的變量賦值。
'prog' awk的程序語句。(注意這裡必須用單拓號:'和'括起,以防被shell
解釋)
progfile awk程序文件。
in_file 輸入文件,可以有多個。值得注意的是awk不修改輸入文件。如果未
指定輸入文件,awk將接受標准輸入,並將結果顯示在標准輸出上。awk支持輸入輸出重
定向(<、>、>>、<<以及|)。
awk支持模式匹配,若沒有給出模式,則對於輸入文件中的所有行都有匹配的。
二、簡單的應用:
例1:顯示文件myfile中含有字符串"sun"的所有行:
awk '/sun/ {print}' myfile
在這裡,模式/sun/匹配輸入文件myfile中所有含有字符串'sun'的行並對其進行操作,
而程序語句print完成對該行的打印。
你也可以使用,號分開兩模式以選定某個范圍:
例2:顯示文件myfile中第一個匹配Sun或sun的行與第一個匹配Moon或moon行之間
的行:
awk '/[Ss]un/,/[Mm]oon/ {print}' myfile
三、awk的字段:
awk的一個強大的功能是支持對字段的操作,這是grep和sed不能實現的。
所謂的字段,即是行中的一部分。在awk中,一般的情況下,將文本文件中的一行視
為一個記錄,而將行中的不同部分稱為“字段”。awk用$1,$2...的形式順序的表示行中的
不同部分即不同字段。一般情況下awk將空白符視為字段間的分隔符,在awk中,用一個內
置的FS變量來確定所使用的字段分隔符。awk允許用-F先項改變默認的字段分隔符。同樣,
在awk中你也可以通過修改記錄分隔符變量RS來改變默認的記錄分隔符。
在awk中用內置變量NR來表示當前工作的記錄數。我們可以將其應用於模式匹配中用
來指定工作范圍:
例3:顯示文本文件myfile中第七行到第十五行中以字符%分隔的第一字段,第三字段和
第七字段:
awk -F % 'NR==7,NR==15 {printf $1 $3 $7}' myfile
四、printf語句
awk可以通過調用用一對單引號括起來的一系列語句來完成一些較為復雜的功能。前面
我們已經遇到過的print就是awk的語句之一。awk也支持獨立的awk程序的調用,其方法是在
命令行中加上-f <程序文件名>參數。
awk融合了許多C語言的待點,因此,如果你熟悉C語言的話對使用awk將有極大的幫助,
實際上,awk中有許多引用形式都是從C語言借用過來的,如我們下面要看到的printf函數就
是一個例子。
如果你熟悉C語言,你也許會懷念其中的printf函數,它提供的強大格式輸出功能曾經
帶我們許多的方便。幸運的是,我們在awk中又和它重逢了。awk中printf幾乎與C語言中一模
一樣,如果你熟悉C語言的話,你完全可以照C語言的模式使用awk中的printf。因此在這裡,
我們只給出一個例子,如果你不熟悉的話,請隨便找一本C語言的入門書翻翻。
例4:顯示文件myfile中的行號和第3字段:
$awk '{printf"%03d%s\n",NR,$1}' myfile
值得注意的一點是awk中的內置變量(如這裡的NR)不須要以$開頭。
對於awk中的其它語句,我們將在後面繼續討論。
五、awk程序設計
前面曾經說過awk提供了整套程序設計語言,包括變量、關系判斷、流程控制等等,下面
我們分別說說其中的用法:
(一)、變量:
awk允許在程序語言中設置變量,事實上,提供變量的功能是程序設計語言的其本要求,
不提供變量的程序設計語言本人還從未見過。awk提供兩種變量,一種是awk內置的變量,如前面
提到的NR、RS都屬於此種范疇,如果你還知道awk提供了哪些其它的內置變量,請參考本文後面
的附錄。awk也允許用戶在awk程序語句中定義並調用自已的變量。與C語言不同的是,awk中不需
要對變量進行初始化,awk根據其在awk中第一次出現的形式和上下文確定其具體的數據類型。
當變量類型不確定時,awk設定其為字符串類型。
(二)、運算與判斷:
awk支持C語言提供的大多數運算:如+、-、*、/、%等等,也支持關系判斷,如<、>、>=
等等,也支持用邏輯運算符:!(非)、&&(與)、||(或)和()進行多重判斷,這大大增強了awk
的功能。
awk也支持C語言中類似++、--、+=、-=、=+、=-之類的功能,這給熟悉C語言的使用者編寫
awk程序帶來了極大的方便。
在awk中為了實現某些運算功能,提供了一些內置的函數,如log、sqr、cos、sin等等,同
時,awk也提供了用於對字符串進行操作(運算)的函數如length、substr等等。
awk提供的具體的運算與判斷功能請參考文後的附錄。
(三)、流程控制
awk提供了完備的類似C語言的流程控制語句,這給我們編程帶來了極大的方便。
1、BEGIN和END
在awk中兩個特別的表達式,BEGIN和END可用於pattern中,任何在BEGIN之後列出的操作(
在{}內)將在awk開始掃描輸入之前執行,而END之後列出的操作將在掃描完全部的輸入之後報廢行。
因此,通常使用BEGIN來顯示變量和預置(初始化)變量,使用END來輸出最終結果。
例5:累計銷售文件xs中的銷售金額(假設銷售金額在記錄的第三字段):
$awk
>'BEGIN { FS=":";print "統計銷售金額";total=0}
>{print $3;total=total+$3;}
>END {printf "銷售金額總計:%.2f",total}' sx
(注:>是shell提供的第二提示符,如要在shell程序awk語句和awk語言中換行,則需在行尾加
反斜槓\)
在這裡BEGIN預置了內部變量FS(字段分隔符)和自定義變量total,同時在掃描之前顯示出輸出
行頭。而END則在掃描完成後打印出總合計。
2、流程控制語句
awk提供了完備的流程控制語句,其用法與C語言類似。下面我們一一加以說明:
if...else語句:
格式:
if(表達式)
語句1
else
語句2
格式中"語句1"可以是多個語句,如果你為了方便awk判斷也方便你自已閱讀,你最好將多個語句
用{}括起來。
awk分枝結構允許嵌套,其格式為
if(表達式1)
{if(表達式2)
語句1
else
語句2
}
語句3
else {if(表達式3)
語句4
else
語句5
}
語句6
當然實際操作過程中你可能不會用到如此復雜的分枝結構,這裡只是為了給出其樣式罷了。
while語句
格式為
while(表達式)
語句
for語句
格式為:
for(初始表達式;終止條件;步長表達式)
語句
在awk while和for語句中允許使用break,continue語句來控制流程走向,也允許使用exit這樣的
語句來退出。
好了,awk就介紹到這裡,說實在話,就這些內容都是awk的初步知識,電腦永遠是前進的科學,
要想跟上它的步伐就得不斷前行,但願本篇能在你前行的漫漫長途中鋪平一段小小的路程,能如此,則
願已償。
附錄:
awk內置變量
變量名 含義
ARGC 命令行參數個數
ARGV 命令行參數數組
FILENAME string=當前輸入的文件名
FNR 在當前文件中當前記錄數(對輸入文件起始為1)
FS 輸入字段分隔符
NF 當前記錄的字段數
NR 當前記錄數(為全部輸入文件)
OFMT 數值的輸出格式(默認為%.6g)
OFS 輸出字段的分隔符(默認為空格)
ORS 輸出記錄分隔符(默認為換行符)
RS 輸入記錄分隔符(默認為換行符)
awk允許的測試:
操作符 含義
x==y x等於y?
x!=y x不等於y?
x>y x大於y?
x>=y x大於或等於y?
x x<=y x小於或等於y?
x~re x匹配正則表達式re?
x!~re x不匹配正則表達式re?
awk的操作符(按優先級升序排列)
= 、+=、 -=、 *= 、/= 、 %=
||
&&
> >= < <= == != ~ !~
xy (字符串連結,'x''y'變成"xy")
+ -
* / %
++ --
awk的函數
int(x) 對x取整
rand 取 0到1之間的隨機數
srand(x) 設置x為rand的新輸入值
cos(x) 給出x的余弦值
sin(x) 給出x的正弦值
atan2(x,y) 給出y/x的正切值
exp(x) 給出e的x次冪
log(x) 給出x的常用對數值(基為e)
sqrt(x) 給出x的正平方根值
exit(x) 結束awk程序,若有x值,則返回x,否則返回0.
index(s,t) 返回t在s中的第一個開始位置,如t不是s的子串,則返回0]
length(x) 求x的長度(字符個數)
substr(s,x,y) 在字符串s中取得從x個字符開始的長度為y的子字符串.
Copyright © Linux教程網 All Rights Reserved