這節詳細介紹awk內置函數,主要分以下3種類似:算數函數、字符串函數、其它一般函數、時間函數
一、算術函數:
以下算術函數執行與 C 語言中名稱相同的子例程相同的操作:
函數名 | 說明 |
atan2( y, x ) | 返回 y/x 的反正切。 |
cos( x ) | 返回 x 的餘弦;x 是弧度。 |
sin( x ) | 返回 x 的正弦;x 是弧度。 |
exp( x ) | 返回 x 冪函數。 |
log( x ) | 返回 x 的自然對數。 |
sqrt( x ) | 返回 x 平方根。 |
int( x ) | 返回 x 的截斷至整數的值。 |
rand( ) | 返回任意數字 n,其中 0 <= n < 1。 |
srand( [Expr] ) | 將 rand 函數的種子值設置爲 Expr 參數的值,或如果省略 Expr 參數則使用某天的時間。返回先前的種子值。 |
舉例說明:
[chengmo@centos5 ~]$ awk 'BEGIN{OFMT="%.3f";fs=sin(1);fe=exp(10);fl=log(10);fi=int(3.1415);print fs,fe,fl,fi;}'
0.841 22026.466 2.303 3
OFMT 設置輸出數據格式是保留3位小數
獲得隨機數:
[chengmo@centos5 ~]$ awk 'BEGIN{srand();fr=int(100*rand());print fr;}'
78
[chengmo@centos5 ~]$ awk 'BEGIN{srand();fr=int(100*rand());print fr;}'
31
[chengmo@centos5 ~]$ awk 'BEGIN{srand();fr=int(100*rand());print fr;}'41
二、字符串函數是:
函數 | 說明 |
gsub( Ere, Repl, [ In ] ) | 除了正則表達式所有具體值被替代這點,它和 sub 函數完全一樣地執行,。 |
sub( Ere, Repl, [ In ] ) | 用 Repl 參數指定的字符串替換 In 參數指定的字符串中的由 Ere 參數指定的擴展正則表達式的第一個具體值。sub 函數返回替換的數量。出現在 Repl 參數指定的字符串中的 &(和符號)由 In 參數指定的與 Ere 參數的指定的擴展正則表達式匹配的字符串替換。如果未指定 In 參數,缺省值是整個記錄($0 記錄變量)。 |
index( String1, String2 ) | 在由 String1 參數指定的字符串(其中有出現 String2 指定的參數)中,返回位置,從 1 開始編號。如果 String2 參數不在 String1 參數中出現,則返回 0(零)。 |
length [(String)] | 返回 String 參數指定的字符串的長度(字符形式)。如果未給出 String 參數,則返回整個記錄的長度($0 記錄變量)。 |
blength [(String)] | 返回 String 參數指定的字符串的長度(以字節爲單位)。如果未給出 String 參數,則返回整個記錄的長度($0 記錄變量)。 |
substr( String, M, [ N ] ) | 返回具有 N 參數指定的字符數量子串。子串從 String 參數指定的字符串取得,其字符以 M 參數指定的位置開始。M 參數指定爲將 String 參數中的第一個字符作爲編號 1。如果未指定 N 參數,則子串的長度將是 M 參數指定的位置到 String 參數的末尾 的長度。 |
match( String, Ere ) | 在 String 參數指定的字符串(Ere 參數指定的擴展正則表達式出現在其中)中返回位置(字符形式),從 1 開始編號,或如果 Ere 參數不出現,則返回 0(零)。RSTART 特殊變量設置爲返回值。RLENGTH 特殊變量設置爲匹配的字符串的長度,或如果未找到任何匹配,則設置爲 -1(負一)。 |
split( String, A, [Ere] ) | 將 String 參數指定的參數分割爲數組元素 A[1], A[2], . . ., A[n],並返回 n 變量的值。此分隔可以通過 Ere 參數指定的擴展正則表達式進行,或用當前字段分隔符(FS 特殊變量)來進行(如果沒有給出 Ere 參數)。除非上下文指明特定的元素還應具有一個數字值,否則 A 數組中的元素用字符串值來創建。 |
tolower( String ) | 返回 String 參數指定的字符串,字符串中每個大寫字符將更改爲小寫。大寫和小寫的映射由當前語言環境的 LC_CTYPE 範疇定義。 |
toupper( String ) | 返回 String 參數指定的字符串,字符串中每個小寫字符將更改爲大寫。大寫和小寫的映射由當前語言環境的 LC_CTYPE 範疇定義。 |
sprintf(Format, Expr, Expr, . . . ) | 根據 Format 參數指定的 printf 子例程格式字符串來格式化 Expr 參數指定的表達式並返回最後生成的字符串。 |
Ere都可以是正則表達式
gsub,sub使用
[chengmo@centos5 ~]$ awk 'BEGIN{info="this is a test2010test!";gsub(/[0-9]+/,"!",info);print info}'
this is a test!test!
在 info中查找滿足正則表達式,/[0-9]+/ 用””替換,並且替換後的值,賦值給info 未給info值,默認是$0
查找字符串(index使用)
[wangsl@centos5 ~]$ awk 'BEGIN{info="this is a test2010test!";print index(info,"test")?"ok":"no found";}'
ok未找到,返回0
正則表達式匹配查找(match使用)
[wangsl@centos5 ~]$ awk 'BEGIN{info="this is a test2010test!";print match(info,/[0-9]+/)?"ok":"no found";}'
ok
截取字符串(substr使用)
[wangsl@centos5 ~]$ awk 'BEGIN{info="this is a test2010test!";print substr(info,4,10);}'
s is a tes從第 4個 字符開始,截取10個長度字符串
字符串分割(split使用)
[chengmo@centos5 ~]$ awk 'BEGIN{info="this is a test";split(info,tA," ");print length(tA);for(k in tA){print k,tA[k];}}'
4
4 test
1 this
2 is
3 a
分割info,動態創建數組tA,這裏比較有意思,awk for …in 循環,是一個無序的循環。 並不是從數組下標1…n ,因此使用時候需要注意。
格式化字符串輸出(sprintf使用)
格式化字符串格式:
其中格式化字符串包括兩部分內容: 一部分是正常字符, 這些字符將按原樣輸出; 另一部分是格式化規定字符, 以"%"開始, 後跟一個或幾個規定字符,用來確定輸出內容格式。
格式符 說明 %d 十進制有符號整數 %u 十進制無符號整數 %f 浮點數 %s 字符串 %c 單個字符 %p 指針的值 %e 指數形式的浮點數 %x %X 無符號以十六進制表示的整數 %o 無符號以八進制表示的整數 %g 自動選擇合適的表示法
[chengmo@centos5 ~]$ awk 'BEGIN{n1=124.113;n2=-1.224;n3=1.2345; printf("%.2f,%.2u,%.2g,%X,%o\n",n1,n2,n3,n1,n1);}'
124.11,18446744073709551615,1.2,7C,174
三、一般函數是:
函數 | 說明 |
close( Expression ) | 用同一個帶字符串值的 Expression 參數來關閉由 print 或 printf 語句打開的或調用 getline 函數打開的文件或管道。如果文件或管道成功關閉,則返回 0;其它情況下返回非零值。如果打算寫一個文件,並稍後在同一個程序中讀取文件,則 close 語句是必需的。 |
system(Command ) | 執行 Command 參數指定的命令,並返回退出狀態。等同於 system 子例程。 |
Expression | getline [ Variable ] | 從來自 Expression 參數指定的命令的輸出中通過管道傳送的流中讀取一個輸入記錄,並將該記錄的值指定給 Variable 參數指定的變量。如果當前未打開將 Expression 參數的值作爲其命令名稱的流,則創建流。創建的流等同於調用 popen 子例程,此時 Command 參數取 Expression 參數的值且 Mode 參數設置爲一個是 r 的值。只要流保留打開且 Expression 參數求得同一個字符串,則對 getline 函數的每次後續調用讀取另一個記錄。如果未指定 Variable 參數,則 $0 記錄變量和 NF 特殊變量設置爲從流讀取的記錄。 |
getline [ Variable ] < Expression | 從 Expression 參數指定的文件讀取輸入的下一個記錄,並將 Variable 參數指定的變量設置爲該記錄的值。只要流保留打開且 Expression 參數對同一個字符串求值,則對 getline 函數的每次後續調用讀取另一個記錄。如果未指定 Variable 參數,則 $0 記錄變量和 NF 特殊變量設置爲從流讀取的記錄。 |
getline [ Variable ] | 將 Variable 參數指定的變量設置爲從當前輸入文件讀取的下一個輸入記錄。如果未指定 Variable 參數,則 $0 記錄變量設置爲該記錄的值,還將設置 NF、NR 和 FNR 特殊變量。 |
打開外部文件(close用法)
[chengmo@centos5 ~]$ awk 'BEGIN{while("cat /etc/passwd"|getline){print $0;};close("/etc/passwd");}'
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
逐行讀取外部文件(getline使用方法)
[chengmo@centos5 ~]$ awk 'BEGIN{while(getline < "/etc/passwd"){print $0;};close("/etc/passwd");}'
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
[chengmo@centos5 ~]$ awk 'BEGIN{print "Enter your name:";getline name;print name;}'
Enter your name:
chengmo
chengmo
調用外部應用程序(system使用方法)
[chengmo@centos5 ~]$ awk 'BEGIN{b=system("ls -al");print b;}'
total 42092
drwxr-xr-x 14 chengmo chengmo 4096 09-30 17:47 .
drwxr-xr-x 95 root root 4096 10-08 14:01 ..
b返回值,是執行結果。
四、時間函數
函數名 | 說明 |
mktime( YYYY MM DD HH MM SS[ DST]) | 生成時間格式 |
strftime([format [, timestamp]]) | 格式化時間輸出,將時間戳轉爲時間字符串 具體格式,見下表. |
systime() | 得到時間戳,返回從1970年1月1日開始到當前時間(不計閏年)的整秒數 |
創建指定時間(mktime使用)
[chengmo@centos5 ~]$ awk 'BEGIN{tstamp=mktime("2001 01 01 12 12 12");print strftime("%c",tstamp);}'
2001年01月01日 星期一 12時12分12秒
[chengmo@centos5 ~]$ awk 'BEGIN{tstamp1=mktime("2001 01 01 12 12 12");tstamp2=mktime("2001 02 01 0 0 0");print tstamp2-tstamp1;}'
2634468求2個時間段中間時間差,介紹了strftime使用方法
[chengmo@centos5 ~]$ awk 'BEGIN{tstamp1=mktime("2001 01 01 12 12 12");tstamp2=systime();print tstamp2-tstamp1;}'
308201392
strftime日期和時間格式說明符
格式 描述 %a 星期幾的縮寫(Sun) %A 星期幾的完整寫法(Sunday) %b 月名的縮寫(Oct) %B 月名的完整寫法(October) %c 本地日期和時間 %d 十進制日期 %D 日期 08/20/99 %e 日期,如果只有一位會補上一個空格 %H 用十進制表示24小時格式的小時 %I 用十進制表示12小時格式的小時 %j 從1月1日起一年中的第幾天 %m 十進制表示的月份 %M 十進制表示的分鐘 %p 12小時表示法(AM/PM) %S 十進制表示的秒 %U 十進制表示的一年中的第幾個星期(星期天作爲一個星期的開始) %w 十進制表示的星期幾(星期天是0) %W 十進制表示的一年中的第幾個星期(星期一作爲一個星期的開始) %x 重新設置本地日期(08/20/99) %X 重新設置本地時間(12:00:00) %y 兩位數字表示的年(99) %Y 當前月份 %Z 時區(PDT) %% 百分號(%)
附2:
內置的字符串函數 awk內置字符串函數 g s u b ( r, s ) 在整個$ 0中用s替代r g s u b ( r, s , t ) 在整個t中用s替代r i n d e x ( s , t ) 返回s中字符串t的第一位置 l e n g t h ( s ) 返回s長度 m a t c h ( s , r ) 測試s是否包含匹配r的字符串 s p l i t ( s , a , f s ) 在f s上將s分成序列a s p r i n t ( f m t , e x p ) 返回經f m t格式化後的e x p s u b ( r, s ) 用$ 0中最左邊最長的子串代替s s u b s t r ( s , p ) 返回字符串s中從p開始的後綴部分 s u b s t r ( s , p , n ) 返回字符串s中從p開始長度爲n的後綴部分 複製代碼 g s u b函數有點類似於s e d查找和替換。它允許替換一個字符串或字符爲另一個字符串或字符,並以正則表達式的形式執行。第一個函數作用於記錄$ 0,第二個g s u b函數允許指定目標,然而,如果未指定目標,缺省爲$ 0。 i n d e x(s,t)函數返回目標字符串s中查詢字符串t的首位置。l e n g t h函數返回字符串s字符長度。 m a t c h函數測試字符串s是否包含一個正則表達式r定義的匹配。s p l i t使用域分隔符f s將字符串s劃分爲指定序列a。 s p r i n t函數類似於p r i n t f函數(以後涉及),返回基本輸出格式f m t的結果字符串e x p。 s u b(r,s)函數將用s替代$ 0中最左邊最長的子串,該子串被( r)匹配。 s u b(s,p)返回字符串s在位置p後的後綴。s u b s t r(s,p,n)同上,並指定子串長度爲n。 現在看一看a w k中這些字符串函數的功能。 1. gsub 要在整個記錄中替換一個字符串爲另一個,使用正則表達式格式, /目標模式/,替換模式/。例如改變學生序號4 8 4 2到4 8 9 9: [root@Linux_chenwy root]# cd /usr/sam [root@Linux_chenwy sam]# awk 'gsub(/4842/,4899){print $0}' grade.txt J.Troll 07/99 4899 Brown-3 12 26 26 複製代碼 [root@Linux_chenwy sam]# awk 'gsub(/4842/,4899)' grade.txt J.Troll 07/99 4899 Brown-3 12 26 26 複製代碼 2. index 查詢字符串s中t出現的第一位置。必須用雙引號將字符串括起來。例如返回目標字符串B u n n y中n y出現的第一位置,即字符個數。 [root@Linux_chenwy sam]# awk 'BEGIN {print index("Bunny","ny")}' grade.txt 4 複製代碼 3. length 返回所需字符串長度,例如檢驗字符串J . Tr o l l返回名字及其長度,即人名構成的字符個數 [root@Linux_chenwy sam]# awk '$1=="J.Troll" {print length($1)" "$1}' grade.txt 7 J.Troll 複製代碼 還有一種方法,這裏字符串加雙引號。 [root@Linux_chenwy sam]# awk 'BEGIN{print length("A FEW GOOD MEN")}' 14 複製代碼 4. match m a t c h測試目標字符串是否包含查找字符的一部分。可以對查找部分使用正則表達式,返回值爲成功出現的字符排列數。如果未找到,返回0,第一個例子在A N C D中查找d。因其不存在,所以返回0。第二個例子在A N C D中查找D。因其存在,所以返回A N C D中D出現的首位置字符數。第三個例子在學生J . L u l u中查找u。 [root@Linux_chenwy sam]# awk 'BEGIN{print match("ANCD",/d/)}' 0 [root@Linux_chenwy sam]# awk 'BEGIN{print match("ANCD",/D/)}' 4 [root@Linux_chenwy sam]# awk '$1=="J.Lulu" {print match($1,"u")}' grade.txt 4 複製代碼 5. split 使用s p l i t返回字符串數組元素個數。工作方式如下:如果有一字符串,包含一指定分隔符- ,例如A D2 - K P 9 - J U 2 - L P - 1,將之劃分成一個數組。使用s p l i t,指定分隔符及數組名。此例中,命令格式爲( " A D 2 - K P 9 - J U 2 - L P - 1 ",p a r t s _ a r r a y," - "),s p l i t然後返回數組下標數,這裏結果爲4。 [root@Linux_chenwy sam]# awk 'BEGIN {print split("123-456-789",pats_array,"-")}'3 複製代碼 還有一個例子使用不同的分隔符。 [root@Linux_chenwy sam]# awk 'BEGIN {print split("123#456#789",myarray,"#")}' 3 複製代碼 這個例子中,s p l i t返回數組m y a r r a y的下標數。數組m y a r r a y取值如下: myarray[1]=123 myarray[2]=456 myarray[3]=789 複製代碼 結尾部分講述數組概念。 6. sub 使用s u b發現並替換模式的第一次出現位置。字符串S T R包含‘poped popo pill’,執行下列s u b命令s u b(/ o p /," o p ",S T R)。模式o p第一次出現時,進行替換操作,返回結果如下:‘pO Ped pope pill’。 如:學生J . Tr o l l的記錄有兩個值一樣,“目前級別分”與“最高級別分”。只改變第一個爲2 9,第二個仍爲2 4不動,操作命令爲s u b(/ 2 6 /," 2 9 ",$ 0),只替換第一個出現2 4的位置。注意J . Tr o l l記錄需存在。 [root@Linux_chenwy sam]# awk '$1=="J.Troll" sub(/26/,"29",$0)' grade.txt M.Tans 5/99 48311 Green 8 40 44 J.Lulu 06/99 48317 green 9 24 29 P.Bunny 02/99 48 Yellow 12 35 28 J.Troll 07/99 4842 Brown-3 12 29 26 L.Tansl 05/99 4712 Brown-2 12 30 28 複製代碼 7. substr s u b s t r是一個很有用的函數。它按照起始位置及長度返回字符串的一部分。例子如下: [root@Linux_chenwy sam]# awk '$1=="L.Tansl" {print substr($1,1,3)}' grade.txt L.T 複製代碼 上面例子中,指定在域1的第一個字符開始,返回其前面5個字符。 如果給定長度值遠大於字符串長度, a w k將從起始位置返回所有字符,要抽取L Ta n s l - e y的姓,只需從第3個字符開始返回長度爲7。可以輸入長度9 9,a w k返回結果相同。 [root@Linux_chenwy sam]# awk '$1=="L.Tansl" {print substr($1,1,99)}' grade.txt L.Tansl 複製代碼 s u b s t r的另一種形式是返回字符串後綴或指定位置後面字符。這裏需要給出指定字符串及其返回字串的起始位置。例如,從文本文件中抽取姓氏,需操作域1,並從第三個字符開始: [root@Linux_chenwy sam]# awk '{print substr($1,3)}' grade.txt Tans Lulu Bunny Troll Tansl 複製代碼 還有一個例子,在B E G I N部分定義字符串,在E N D部分返回從第t個字符開始抽取的子串。 [root@Linux_chenwy sam]# awk 'BEGIN{STR="A FEW GOOD MEN"}END{print substr(STR,7)}' grade.txt GOOD MEN 複製代碼 8. 從s h e l l中向a w k傳入字符串 a w k腳本大多隻有一行,其中很少是字符串表示的。大多要求在一行內完成a w k腳本,這一點通過將變量傳入a w k命令行會變得很容易。現就其基本原理講 述一些例子。 使用管道將字符串s t a n d - b y傳入a w k,返回其長度。 [root@Linux_chenwy sam]# echo "Stand-by" | awk '{print length($0)}' 8 複製代碼 設置文件名爲一變量,管道輸出到a w k,返回不帶擴展名的文件名。 [root@Linux_chenwy sam]# STR="mydoc.txt" [root@Linux_chenwy sam]# echo $STR|awk '{print substr($STR,1,5)}' mydoc 複製代碼 設置文件名爲一變量,管道輸出到a w k,只返回其擴展名。 [root@Linux_chenwy sam]# STR="mydoc.txt" [root@Linux_chenwy sam]# echo $STR|awk '{print substr($STR,7)}' txt
|
以上是awk常見 內置函數使用及說明,希望對大家有所幫助。