Unix awk使用手冊(下)

awk函數的定義方法如下: 

function 函數名(參數表){ 
函數體 


在gawk中允許將function省略爲func,但其它版本的awk不允許。函數名必須是一個合法的標誌符,參數表中可以不提供參數(但在調用函數時函數名後的一對括號仍然是不可缺少的),也可以提供一個或多個參數。與C語言相似,awk的參數也是通過值來傳遞的。 

在awk中調用函數比較簡單,其方法與C語言相似,但awk比C語言更爲靈活,它不執行參數有效性檢查。換句話說,在你調用函數時,可以列出比函數預計(函數定義中規定)的多或少的參數,多餘的參數會被awk所忽略,而不足的參數,awk將它們置爲缺省值0或空字符串,具體置爲何值,將取決於參數的使用方式。 

awk函數有兩種返回方式:隱式返回和顯式返回。當awk執行到函數的結尾時,它自動地返回到調用程序,這是函數是隱式返回的。如果需要在結束之前退出函數,可以明確地使用返回語句提前退出。方法是在函數中使用形如:return 返回值 格式的語句。 

例:下面的例子演示了函數的使用。在這個示例中,定義了一個名爲print_header的函數,該函數調用了兩個參數FileName和PageNum,FileName參數傳給函數當前使用的文件名,PageNum參數是當前頁的頁號。這個函數的功能是打印(顯示)出當前文件的文件名,和當前頁的頁號。完成這個功能後,這個函數將返回下一頁的頁號。 

nawk 
>;'BEGIN{pageno=1;file=FILENAME 
>;pageno=print_header(file,pageno);#調用函數print_header 
>;printf("當前頁頁號是:%d\n",pageno); 
>;} 

>;#定義函數print_header 
>;function print_header(FileName,PageNum){ 
>;printf("%s %d\n",FileName,PageNum); >;PageNum++;return PageNUm; 
>;} 
>;}' myfile 

執行這個程序將顯示如下內容: 

myfile 1 
當前頁頁號是:2 

awk高級輸入輸出 

1.讀取下一條記錄: 

awk的next語句導致awk讀取下一個記錄並完成模式匹配,然後立即執行相應的操作。通常它用匹配的模式執行操作中的代碼。next導致這個記錄的任何額外匹配模式被忽略。 

2.簡單地讀取一條記錄 

awk的 getline語句用於簡單地讀取一條記錄。如果用戶有一個數據記錄類似兩個物理記錄,那麼getline將尤其有用。它完成一般字段的分離(設置字段變量$0 FNR NF NR)。如果成功則返回1,失敗則返回0(到達文件尾)。如果需簡單地讀取一個文件,則可以編寫以下代碼: 

例:示例getline的使用 

{while(getline==1) 

#process the inputted fields 



也可以使getline保存輸入數據在一個字段中,而不是通過使用getline variable的形式處理一般字段。當使用這種方式時,NF被置成0,FNR和NR被增值。 

用戶也可以使用getline<&quot;filename&quot;方式從一個給定的文件中輸入數據,而不是從命令行所列內容輸入數據。此時,getline將完成一般字段分離(設置字段變量$0和NF)。如果文件不存在,返回-1,成功,返回1,返回0表示失敗。用戶可以從給定文件中讀取數據到一個變量中,也可以用stdin(標準輸入設備)或一個包含這個文件名的變量代替filename。值得注意的是當使用這種方式時不修改FNR和NR。 

另一種使用getline語句的方法是從UNIX命令接受輸入,例如下面的例子: 

例:示例從UNIX命令接受輸入 

{while(&quot;who -u&quot;|getline) 

#process each line from the who command 



當然,也可以使用如下形式: 

&quot;command&quot; | getline variable 

3.關閉文件: 

awk中允許在程序中關閉一個輸入或輸出文件,方法是使用awk的close語句。 

close(&quot;filename&quot;) 

filename可以是getline打開的文件(也可以是stdin,包含文件名的變量或者getline使用的確切命令)。或一個輸出文件(可以是stdout,包含文件名的變量或使用管道的確切命令)。 

4.輸出到一個文件: 

awk中允許用如下方式將結果輸出到一個文件: 

printf(&quot;hello word!\n&quot;)>;&quot;datafile&quot; 
或 
printf(&quot;hello word!\n&quot;)>;>;&quot;datafile&quot; 

5.輸出到一個命令 

awk中允許用如下方式將結果輸出到一個命令: 

printf(&quot;hello word!\n&quot;)|&quot;sort-t','&quot; 

awk與shell script混合編程 

因爲awk可以作爲一個shell命令使用,因此awk能與shell批處理程序很好的融合在一起,這給實現awk與shell程序的混合編程提供了可能。實現混合編程的關鍵是awk與shell script之間的對話,換言之,就是awk與shell script之間的信息交流:awk從shell script中獲取所需的信息(通常是變量的值)、在awk中執行shell命令行、shell script將命令執行的結果送給awk處理以及shell script讀取awk的執行結果等等。 

1.awk讀取Shell script程序變量 

在awk中我們可以通過“'$變量名'”的方式讀取sell scrpit程序中的變量。 

例:在下面的示例中,我們將讀取sell scrpit程序中的變量Name,該變量存放的是文本myfile的撰寫者,awk將打印出這個人名。 

$cat writename 

# @(#) 




Name=&quot;張三&quot; nawk 'BEGIN {name=&quot;'Name'&quot;;\ printf(&quot;\t%s\t撰寫者%s\n&quot;,FILENAME,name&quot;);}\ 
{...}END{...}' myfile 




2.將shell命令的執行結果送給awk處理 

作爲信息傳送的一種方法,我們可以將一條shell命令的結果通過管道線(|)傳遞給awk處理: 

例:示例awk處理shell命令的執行結果 

$who -u | awk '{printf(&quot;%s正在執行%s\n&quot;,$2,$1)}' 

該命令將打印出註冊終端正在執行的程序名。 

3.shell script程序讀awk的執行結果 

爲了實現shell script程序讀取awk執行的結果,我們可以採取一些特殊的方法,例如我們可以用變量名=`awk語句`的形式將awk執行的結果存放入一個shell script變量。當然也可以用管道線的方法將awk執行結果傳遞給shell script程序處理。 

例:作爲傳送消息的機制之一,UNIX提供了一個向其所有用戶傳送消息的命令wall(意思是write to all寫給所有用戶),該命令允許向所有工作中的用戶(終端)發送消息。爲此,我們可以通過一段shell批處理程序wall.shell來模擬這一程序(事實上比較老的版本中wall就是一段shell批處理程序: 

$cat wall.shell 

# @(#) wall.shell:發送消息給每個已註冊終端 

cat >;/tmp/$$ 
#用戶錄入消息文本 who -u | awk '{print $2}' | while read tty 
do 
cat /tmp/$$>;$tty 
done 

在這個程序裏,awk接受who -u命令的執行結果,該命令打印出所有已註冊終端的信息,其中第二個字段是已註冊終端的設備名,因此用awk命令析出該設備名,然後用while read tty語句循環讀出這些文件名到變量(shell script變量)tty中,作爲信息傳送的終結地址。 

4.在awk中執行shell命令行----嵌入函數system() 

system()是一個不適合字符或數字類型的嵌入函數,該函數的功能是處理作爲參數傳遞給它的字符串。system對這個參數的處理就是將其作爲命令處理,也就是說將其當作命令行一樣加以執行。這使得用戶在自己的awk程序需要時可以靈活地執行命令或腳本。 

例:下面的程序將使用system嵌入函數打印用戶編制好的報表文件,這個文件存放在名爲myreport.txt的文件中。爲簡約起見,我們只列出了其END部分: 




END {close(&quot;myreport.txt&quot;);system(&quot;lp myreport.txt&quot;);} 

在這個示例中,我們首先使用close語句關閉了文件myreport.txt文件,然後使用system嵌入函數將myreport.txt送入打印機打印。 

寫到這裏,我不得不跟朋友們說再見了,實在地說,這些內容仍然是awk的初步知識,電腦永遠是前進的科學,awk也不例外,本篇所能做的只是在你前行的漫漫長途中鋪平一段小小開端,剩下的路還得靠你自己去走。老實說,如果本文真能給你前行的路上帶來些許的方便,那本人就知足了! 

如對本篇有任何疑問,請E-mail To:[email protected]或到主頁http://chizling.yeah.net中留言。 


附錄: 

1.awk的常規表達式元字符 

\ 換碼序列 
^ 在字符串的開頭開始匹配 
$ 在字符串的結尾開始匹配 
. 與任何單個字符串匹配 
[ABC] 與[]內的任一字符匹配 
[A-Ca-c] 與A-C及a-c範圍內的字符匹配(按字母表順序) 
[^ABC] 與除[]內的所有字符以外的任一字符匹配 
Desk|Chair 與Desk和Chair中的任一個匹配 
[ABC][DEF] 關聯。與A、B、C中的任一字符匹配,且其後要跟D、E、F中的任一個字符。 
* 與A、B或C中任一個出現0次或多次的字符相匹配 
+ 與A、B或C中任何一個出現1次或多次的字符相匹配 
? 與一個空串或A、B或C在任何一個字符相匹配 
(Blue|Black)berry 合併常規表達式,與Blueberry或Blackberry相匹配 

2.awk算術運算符 

運算符 用途 
------------------ 
x^y x的y次冪 
x**y 同上 
x%y 計算x/y的餘數(求模) 
x+y x加y 
x-y x減y 
x*y x乘y 
x/y x除y 
-y 負y(y的開關符號);也稱一目減 
++y y加1後使用y(前置加) 
y++ 使用y值後加1(後綴加) 
--y y減1後使用y(前置減) 
y-- 使用後y減1(後綴減) 
x=y 將y的值賦給x 
x+=y 將x+y的值賦給x 
x-=y 將x-y的值賦給x 
x*=y 將x*y的值賦給x 
x/=y 將x/y的值賦給x x%=y 將x%y的值賦給x 
x^=y 將x^y的值賦給x 
x**=y 將x**y的值賦給x 

3.awk允許的測試: 

操作符 含義 

x==y x等於y 
x!=y x不等於y 
x>;y x大於y 
x>;=y x大於或等於y 
x<y x小於y 
x<=y x小於或等於y? 
x~re x匹配正則表達式re? 
x!~re x不匹配正則表達式re? 

4.awk的操作符(按優先級升序排列) 

= 、+=、 -=、 *= 、/= 、 %= 
|| 
&amp;&amp; 
>; >;= < <= == != ~ !~ 
xy (字符串連結,'x''y'變成&quot;xy&quot;) 
+ - 
* / % 
++ -- 

5.awk內置變量(預定義變量) 

說明:表中v項表示第一個支持變量的工具(下同):A=awk,N=nawk,P=POSIX awk,G=gawk 

V 變量 含義 缺省值 
-------------------------------------------------------- 
N ARGC 命令行參數個數 
G ARGIND 當前被處理文件的ARGV標誌符 
N ARGV 命令行參數數組 
G CONVFMT 數字轉換格式 %.6g 
P ENVIRON UNIX環境變量 
N ERRNO UNIX系統錯誤消息 
G FIELDWIDTHS 輸入字段寬度的空白分隔字符串 
A FILENAME 當前輸入文件的名字 
P FNR 當前記錄數 
A FS 輸入字段分隔符 空格 
G IGNORECASE 控制大小寫敏感0(大小寫敏感) 
A NF 當前記錄中的字段個數 
A NR 已經讀出的記錄數 
A OFMT 數字的輸出格式 %.6g 
A OFS 輸出字段分隔符 空格 
A ORS 輸出的記錄分隔符 新行 
A RS 輸入的記錄他隔符 新行 
N RSTART 被匹配函數匹配的字符串首 
N RLENGTH 被匹配函數匹配的字符串長度 
N SUBSEP 下標分隔符 &quot;\034&quot; 

6.awk的內置函數 

V 函數 用途或返回值 
------------------------------------------------ 
N gsub(reg,string,target) 每次常規表達式reg匹配時替換target中的string 
N index(search,string) 返回string中search串的位置 
A length(string) 求串string中的字符個數 
N match(string,reg) 返回常規表達式reg匹配的string中的位置 
N printf(format,variable) 格式化輸出,按format提供的格式輸出變量variable。 
N split(string,store,delim) 根據分界符delim,分解string爲store的數組元素 
N sprintf(format,variable) 返回一個包含基於format的格式化數據,variables是要放到串中的數據 
G strftime(format,timestamp) 返回一個基於format的日期或者時間串,timestmp是systime()函數返回的時間 
N sub(reg,string,target) 第一次當常規表達式reg匹配,替換target串中的字符串 
A substr(string,position,len) 返回一個以position開始len個字符的子串 
P totower(string) 返回string中對應的小寫字符 
P toupper(string) 返回string中對應的大寫字符 
A atan(x,y) x的餘切(弧度) 
N cos(x) x的餘弦(弧度) 
A exp(x) e的x冪 
A int(x) x的整數部分 
A log(x) x的自然對數值 
N rand() 0-1之間的隨機數 
N sin(x) x的正弦(弧度) 
A sqrt(x) x的平方根 
A srand(x) 初始化隨機數發生器。如果忽略x,則使用system() 
G system() 返回自1970年1月1日以來經過的時間(按秒計算)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章