awk 用法:awk ' pattern {action} '
變量名 含義
ARGC 命令行變元個數
ARGV 命令行變元數組
FILENAME 當前輸入文件名
FNR 當前文件中的記錄號
FS 輸入域分隔符,默認爲一個空格
RS 輸入記錄分隔符
NF 當前記錄裏域個數
NR 到目前爲止記錄數
OFS 輸出域分隔符
ORS 輸出記錄分隔符
一、awk '/101/' file 顯示文件file中包含101的匹配行。
awk '/101/,/105/' file
awk '$1 == 5' file
awk '$1 == "CT"' file 注意必須帶雙引號
awk '$1 * $2 >100 ' file
awk '$2 >5 && $2<=15' file html
二、awk '{print NR,NF,$1,$NF,}' file 顯示文件file的當前記錄號、域數和每一行的第一個和最後一個域。
awk '/101/ {print $1,$2 + 10}' file 顯示文件file的匹配行的第1、二個域加10。
awk '/101/ {print $1$2}' file
awk '/101/ {print $1 $2}' file 顯示文件file的匹配行的第1、二個域,但顯示時域中間沒有分隔符。 node
三、df | awk '$4>1000000 ' 經過管道符得到輸入,如:顯示第4個域知足條件的行。 mysql
四、awk -F "|" '{print $1}' file 按照新的分隔符「|」進行操做。
awk 'BEGIN { FS="[: \t|]" }
{print $1,$2,$3}' file 經過設置輸入分隔符(FS="[: \t|]")修改輸入分隔符。
Sep="|"
awk -F $Sep '{print $1}' file 按照環境變量Sep的值作爲分隔符。
awk -F '[ :\t|]' '{print $1}' file 按照正則表達式的值作爲分隔符,這裏表明空格、:、TAB、|同時作爲分隔符。
awk -F '[][]' '{print $1}' file 按照正則表達式的值作爲分隔符,這裏表明[、] linux
五、awk -f awkfile file 經過文件awkfile的內容依次進行控制。
cat awkfile
/101/{print "\047 Hello! \047"} --遇到匹配行之後打印 ' Hello! '. \047表明單引號。
{print $1,$2} --由於沒有模式控制,打印每一行的前兩個域。 c++
六、awk '$1 ~ /101/ {print $1}' file 顯示文件中第一個域匹配101的行(記錄)。 正則表達式
七、awk 'BEGIN { OFS="%"}
{print $1,$2}' file 經過設置輸出分隔符(OFS="%")修改輸出格式。 sql
八、awk 'BEGIN { max=100 ;print "max=" max} BEGIN 表示在處理任意行以前進行的操做。
{max=($1 >max ?$1:max); print $1,"Now max is "max}' file 取得文件第一個域的最大值。
(表達式1?表達式2:表達式3 至關於:
if (表達式1)
表達式2
else
表達式3
awk '{print ($1>4 ? "high "$1: "low "$1)}' file shell
九、awk '$1 * $2 >100 {print $1}' file 顯示文件中第一個域匹配101的行(記錄)。 express
十、awk '{$1 == 'Chi' {$3 = 'China'; print}' file 找到匹配行後先將第3個域替換後再顯示該行(記錄)。
awk '{$7 %= 3; print $7}' file 將第7域被3除,並將餘數賦給第7域再打印。 編程
十一、awk '/tom/ {wage=$2+$3; printf wage}' file 找到匹配行後爲變量wage賦值並打印該變量。
十二、awk '/tom/ {count++;}
END {print "tom was found "count" times"}' file END表示在全部輸入行處理完後進行處理。
1三、awk 'gsub(/\$/,"");gsub(/,/,""); cost+=$4;
END {print "The total is $" cost>"filename"}' file gsub函數用空串替換$和,再將結果輸出到filename中。
1 2 3 $1,200.00
1 2 3 $2,300.00
1 2 3 $4,000.00
awk '{gsub(/\$/,"");gsub(/,/,"");
if ($4>1000&&$4<2000) c1+=$4;
else if ($4>2000&&$4<3000) c2+=$4;
else if ($4>3000&&$4<4000) c3+=$4;
else c4+=$4; }
END {printf "c1=[%d];c2=[%d];c3=[%d];c4=[%d]\n",c1,c2,c3,c4}"' file
經過if和else if完成條件語句
awk '{gsub(/\$/,"");gsub(/,/,"");
if ($4>3000&&$4<4000) exit;
else c4+=$4; }
END {printf "c1=[%d];c2=[%d];c3=[%d];c4=[%d]\n",c1,c2,c3,c4}"' file
經過exit在某條件時退出,可是仍執行END操做。
awk '{gsub(/\$/,"");gsub(/,/,"");
if ($4>3000) next;
else c4+=$4; }
END {printf "c4=[%d]\n",c4}"' file
經過next在某條件時跳過該行,對下一行執行操做。
1四、awk '{ print FILENAME,$0 }' file1 file2 file3>fileall 把file一、file二、file3的文件內容所有寫到fileall中,格式爲
打印文件並前置文件名。
1五、awk ' $1!=previous { close(previous); previous=$1 }
{print substr($0,index($0," ") +1)>$1}' fileall 把合併後的文件從新分拆爲3個文件。並與原文件一致。
1六、awk 'BEGIN {"date"|getline d; print d}' 經過管道把date的執行結果送給getline,並賦給變量d,而後打印。
1七、awk 'BEGIN {system("echo \"Input your name:\\c\""); getline d;print "\nYour name is",d,"\b!\n"}'
經過getline命令交互輸入name,並顯示出來。
awk 'BEGIN {FS=":"; while(getline< "/etc/passwd" >0) { if($1~"050[0-9]_") print $1}}'
打印/etc/passwd文件中用戶名包含050x_的用戶名。
1八、awk '{ i=1;while(i<NF) {print NF,$i;i++}}' file 經過while語句實現循環。
awk '{ for(i=1;i<NF;i++) {print NF,$i}}' file 經過for語句實現循環。
type file|awk -F "/" '
{ for(i=1;i<NF;i++)
{ if(i==NF-1) { printf "%s",$i }
else { printf "%s/",$i } }}' 顯示一個文件的全路徑。
用for和if顯示日期
awk 'BEGIN {
for(j=1;j<=12;j++)
{ flag=0;
printf "\n%d月份\n",j;
for(i=1;i<=31;i++)
{
if (j==2&&i>28) flag=1;
if ((j==4||j==6||j==9||j==11)&&i>30) flag=1;
if (flag==0) {printf "%02d%02d ",j,i}
}
}
}'
1九、在awk中調用系統變量必須用單引號,若是是雙引號,則表示字符串
Flag=abcd
awk '{print '$Flag'}' 結果爲abcd
awk '{print "$Flag"}' 結果爲$Flag
===============================
$awk 'BEGIN{total=0}{total+=$4}END{print total}' a.txt -----對a.txt文件的第四個域進行求和!
$ awk '/^(no|so)/' test -----打印全部以模式no或so開頭的行。
$ awk '/^[ns]/{print $1}' test -----若是記錄以n或s開頭,就打印這個記錄。
$ awk '$1 ~/[0-9][0-9]$/(print $1}' test -----若是第一個域以兩個數字結束就打印這個記錄。
$ awk '$1 == 100 || $2 < 50' test -----若是第一個或等於100或者第二個域小於50,則打印該行。
$ awk '$1 != 10' test -----若是第一個域不等於10就打印該行。
$ awk '/test/{print $1 + 10}' test -----若是記錄包含正則表達式test,則第一個域加10並打印出來。
$ awk '{print ($1 > 5 ? "ok "$1: "error"$1)}' test -----若是第一個域大於5則打印問號後面的表達式值,不然打印冒號後面的表達式值。
$ awk '/^root/,/^mysql/' test ----打印以正則表達式root開頭的記錄到以正則表達式mysql開頭的記錄範圍內的全部記錄。若是找到一個新的正則表達式root開頭的記錄,則繼續打印直到下一個以正則表達式mysql開頭的記錄爲止,或到文件末尾。
===============================
Table of Contents
awk是一種編程語言,用於在linux/unix下對文本和數據進行處理。數據能夠來自標準輸入、一個或多個文件,或其它命令的輸出。它支持用戶自定義函數和動態正則表達式等先進功能,是linux/unix下的一個強大編程工具。它在命令行中使用,但更可能是做爲腳原本使用。awk的處理文本和數據的方式是這樣的,它逐行掃描文件,從第一行到最後一行,尋找匹配的特定模式的行,並在這些行上進行你想要的操做。若是沒有指定處理動做,則把匹配的行顯示到標準輸出(屏幕),若是沒有指定模式,則全部被操做所指定的行都被處理。awk分別表明其做者姓氏的第一個字母。由於它的做者是三我的,分別是Alfred Aho、Brian Kernighan、Peter Weinberger。gawk是awk的GNU版本,它提供了Bell實驗室和GNU的一些擴展。下面介紹的awk是以GUN的gawk爲例的,在linux系統中已把awk連接到gawk,因此下面所有以awk進行介紹。
awk [options] 'script' var=value file(s)
awk [options] -f scriptfile var=value file(s)
指定輸入文件折分隔符,fs是一個字符串或者是一個正則表達式,如-F:。
賦值一個用戶定義變量。
從腳本文件中讀取awk命令。
對nnn值設置內在限制,-mf選項限制分配給nnn的最大塊數目;-mr選項限制記錄的最大數目。這兩個功能是Bell實驗室版awk的擴展功能,在標準awk中不適用。
在兼容模式下運行awk。因此gawk的行爲和標準的awk徹底同樣,全部的awk擴展都被忽略。
打印簡短的版權信息。
打印所有awk選項和每一個選項的簡短說明。
打印不能向傳統unix平臺移植的結構的警告。
打印關於不能向傳統unix平臺移植的結構的警告。
打開兼容模式。但有如下限制,不識別:\x、函數關鍵字、func、換碼序列以及當fs是一個空格時,將新行做爲一個域分隔符;操做符**和**=不能代替^和^=;fflush無效。
容許間隔正則表達式的使用,參考(grep中的Posix字符類),如括號表達式[[:alpha:]]。
使用program-text做爲源代碼,可與-f命令混用。
打印bug報告信息的版本。
pattern {action} 如$ awk '/root/' test,或$ awk '$3 < 100' test。
二者是可選的,若是沒有模式,則action應用到所有記錄,若是沒有action,則輸出匹配所有記錄。默認狀況下,每個輸入行都是一條記錄,但用戶可經過RS變量指定不一樣的分隔符進行分隔。
模式能夠是如下任意一個:
/正則表達式/:使用通配符的擴展集。
關係表達式:能夠用下面運算符表中的關係運算符進行操做,能夠是字符串或數字的比較,如$2>%1選擇第二個字段比第一個字段長的行。
模式匹配表達式:用運算符~(匹配)和~!(不匹配)。
模式,模式:指定一個行的範圍。該語法不能包括BEGIN和END模式。
BEGIN:讓用戶指定在第一條輸入記錄被處理以前所發生的動做,一般可在這裏設置全局變量。
END:讓用戶在最後一條輸入記錄被讀取以後發生的動做。
Table 1. awk的環境變量
變量 | 描述 |
---|---|
$n | 當前記錄的第n個字段,字段間由FS分隔。 |
$0 | 完整的輸入記錄。 |
ARGC | 命令行參數的數目。 |
ARGIND | 命令行中當前文件的位置(從0開始算)。 |
ARGV | 包含命令行參數的數組。 |
CONVFMT | 數字轉換格式(默認值爲%.6g) |
ENVIRON | 環境變量關聯數組。 |
ERRNO | 最後一個系統錯誤的描述。 |
FIELDWIDTHS | 字段寬度列表(用空格鍵分隔)。 |
FILENAME | 當前文件名。 |
FNR | 同NR,但相對於當前文件。 |
FS | 字段分隔符(默認是任何空格)。 |
IGNORECASE | 若是爲真,則進行忽略大小寫的匹配。 |
NF | 當前記錄中的字段數。 |
NR | 當前記錄數。 |
OFMT | 數字的輸出格式(默認值是%.6g)。 |
OFS | 輸出字段分隔符(默認值是一個空格)。 |
ORS | 輸出記錄分隔符(默認值是一個換行符)。 |
RLENGTH | 由match函數所匹配的字符串的長度。 |
RS | 記錄分隔符(默認是一個換行符)。 |
RSTART | 由match函數所匹配的字符串的第一個位置。 |
SUBSEP | 數組下標分隔符(默認值是\034)。 |
awk把每個以換行符結束的行稱爲一個記錄。
記錄分隔符:默認的輸入和輸出的分隔符都是回車,保存在內建變量ORS和RS中。
$0變量:它指的是整條記錄。如$ awk '{print $0}' test將輸出test文件中的全部記錄。
變量NR:一個計數器,每處理完一條記錄,NR的值就增長1。如$ awk '{print NR,$0}' test將輸出test文件中全部記錄,並在記錄前顯示記錄號。
記錄中每一個單詞稱作「域」,默認狀況下以空格或tab分隔。awk可跟蹤域的個數,並在內建變量NF中保存該值。如$ awk '{print $1,$3}' test將打印test文件中第一和第三個以空格分開的列(域)。
如下幾個是gawk專用的,不適合unix版本的awk。
匹配一個單詞開頭或者末尾的空字符串。
匹配單詞內的空字符串。
匹配一個單詞的開頭的空字符串,錨定開始。
匹配一個單詞的末尾的空字符串,錨定末尾。
匹配一個字母數字組成的單詞。
匹配一個非字母數字組成的單詞。
匹配字符串開頭的一個空字符串。
匹配字符串末尾的一個空字符串。
conditional expression1 ? expression2: expression3,例如:$ awk '{max = {$1 > $3} ? $1: $3: print max}' test。若是第一個域大於第三個域,$1就賦值給max,不然$3就賦值給max。
$ awk '$1 + $2 < 100' test。若是第一和第二個域相加大於100,則打印這些行。
$ awk '$1 > 5 && $2 < 10' test,若是第一個域大於5,而且第二個域小於10,則打印這些行。
範圍模板匹配從第一個模板的第一次出現到第二個模板的第一次出現之間全部行。若是有一個模板沒出現,則匹配到開頭或末尾。如$ awk '/root/,/mysql/' test將顯示root第一次出現到mysql第一次出現之間的全部行。
$ awk '/^(no|so)/' test-----打印全部以模式no或so開頭的行。
$ awk '/^[ns]/{print $1}' test-----若是記錄以n或s開頭,就打印這個記錄。
$ awk '$1 ~/[0-9][0-9]$/(print $1}' test-----若是第一個域以兩個數字結束就打印這個記錄。
$ awk '$1 == 100 || $2 < 50' test-----若是第一個或等於100或者第二個域小於50,則打印該行。
$ awk '$1 != 10' test-----若是第一個域不等於10就打印該行。
$ awk '/test/{print $1 + 10}' test-----若是記錄包含正則表達式test,則第一個域加10並打印出來。
$ awk '{print ($1 > 5 ? "ok "$1: "error"$1)}' test-----若是第一個域大於5則打印問號後面的表達式值,不然打印冒號後面的表達式值。
$ awk '/^root/,/^mysql/' test----打印以正則表達式root開頭的記錄到以正則表達式mysql開頭的記錄範圍內的全部記錄。若是找到一個新的正則表達式root開頭的記錄,則繼續打印直到下一個以正則表達式mysql開頭的記錄爲止,或到文件末尾。
在awk中,變量不須要定義就能夠直接使用,變量類型能夠是數字或字符串。
賦值格式:Variable = expression,如$ awk '$1 ~/test/{count = $2 + $3; print count}' test,上式的做用是,awk先掃描第一個域,一旦test匹配,就把第二個域的值加上第三個域的值,並把結果賦值給變量count,最後打印出來。
awk能夠在命令行中給變量賦值,而後將這個變量傳輸給awk腳本。如$ awk -F: -f awkscript month=4 year=2004 test,上式的month和year都是自定義變量,分別被賦值爲4和2004。在awk腳本中,這些變量使用起來就象是在腳本中創建的同樣。注意,若是參數前面出現test,那麼在BEGIN語句中的變量就不能被使用。
域變量也可被賦值和修改,如$ awk '{$2 = 100 + $1; print }' test,上式表示,若是第二個域不存在,awk將計算表達式100加$1的值,並將其賦值給$2,若是第二個域存在,則用表達式的值覆蓋$2原來的值。再例如:$ awk '$1 == "root"{$1 ="test";print}' test,若是第一個域的值是「root」,則把它賦值爲「test」,注意,字符串必定要用雙引號。
內建變量的使用。變量列表在前面已列出,如今舉個例子說明一下。$ awk -F: '{IGNORECASE=1; $1 == "MARY"{print NR,$1,$2,$NF}'test,把IGNORECASE設爲1表明忽略大小寫,打印第一個域是mary的記錄數、第一個域、第二個域和最後一個域。
BEGIN模塊後緊跟着動做塊,這個動做塊在awk處理任何輸入文件以前執行。因此它能夠在沒有任何輸入的狀況下進行測試。它一般用來改變內建變量的值,如OFS,RS和FS等,以及打印標題。如:$ awk 'BEGIN{FS=":"; OFS="\t"; ORS="\n\n"}{print $1,$2,$3} test。上式表示,在處理輸入文件之前,域分隔符(FS)被設爲冒號,輸出文件分隔符(OFS)被設置爲製表符,輸出記錄分隔符(ORS)被設置爲兩個換行符。$ awk 'BEGIN{print "TITLE TEST"}只打印標題。
END不匹配任何的輸入文件,可是執行動做塊中的全部動做,它在整個輸入文件處理完成後被執行。如$ awk 'END{print "The number of records is" NR}' test,上式將打印全部被處理的記錄數。
awk可以使用shell的重定向符進行重定向輸出,如:$ awk '$1 = 100 {print $1 > "output_file" }' test。上式表示若是第一個域的值等於100,則把它輸出到output_file中。也能夠用>>來重定向輸出,但不清空文件,只作追加操做。
輸出重定向需用到getline函數。getline從標準輸入、管道或者當前正在處理的文件以外的其餘輸入文件得到輸入。它負責從輸入得到下一行的內容,並給NF,NR和FNR等內建變量賦值。若是獲得一條記錄,getline函數返回1,若是到達文件的末尾就返回0,若是出現錯誤,例如打開文件失敗,就返回-1。如:
$ awk 'BEGIN{ "date" | getline d; print d}' test。執行linux的date命令,並經過管道輸出給getline,而後再把輸出賦值給自定義變量d,並打印它。
$ awk 'BEGIN{"date" | getline d; split(d,mon); print mon[2]}' test。執行shell的date命令,並經過管道輸出給getline,而後getline從管道中讀取並將輸入賦值給d,split函數把變量d轉化成數組mon,而後打印數組mon的第二個元素。
$ awk 'BEGIN{while( "ls" | getline) print}',命令ls的輸出傳遞給geline做爲輸入,循環使getline從ls的輸出中讀取一行,並把它打印到屏幕。這裏沒有輸入文件,由於BEGIN塊在打開輸入文件前執行,因此能夠忽略輸入文件。
$ awk 'BEGIN{printf "What is your name?"; getline name < "/dev/tty" } $1 ~name {print "Found" name on line ", NR "."} END{print "See you," name "."} test。在屏幕上打印」What is your name?",並等待用戶應答。當一行輸入完畢後,getline函數從終端接收該行輸入,並把它儲存在自定義變量name中。若是第一個域匹配變量name的值,print函數就被執行,END塊打印See you和name的值。
$ awk 'BEGIN{while (getline < "/etc/passwd" > 0) lc++; print lc}'。awk將逐行讀取文件/etc/passwd的內容,在到達文件末尾前,計數器lc一直增長,當到末尾時,打印lc的值。注意,若是文件不存在,getline返回-1,若是到達文件的末尾就返回0,若是讀到一行,就返回1,因此命令 while (getline < "/etc/passwd")在文件不存在的狀況下將陷入無限循環,由於返回-1表示邏輯真。
能夠在awk中打開一個管道,且同一時刻只能有一個管道存在。經過close()可關閉管道。如:$ awk '{print $1, $2 | "sort" }' test END {close("sort")}。awd把print語句的輸出經過管道做爲linux命令sort的輸入,END塊執行關閉管道操做。
system函數能夠在awk中執行linux的命令。如:$ awk 'BEGIN{system("clear")'。
fflush函數用以刷新輸出緩衝區,若是沒有參數,就刷新標準輸出的緩衝區,若是以空字符串爲參數,如fflush(""),則刷新全部文件和管道的輸出緩衝區。
awk中的條件語句是從C語言中借鑑過來的,可控制程序的流程。
格式: {if (expression){ statement; statement; ... } }
$ awk '{if ($1 <$2) print $2 "too high"}' test。若是第一個域小於第二個域則打印。
$ awk '{if ($1 < $2) {count++; print "ok"}}' test.若是第一個域小於第二個域,則count加一,並打印ok。
格式: {if (expression){ statement; statement; ... } else{ statement; statement; ... } }
$ awk '{if ($1 > 100) print $1 "bad" ; else print "ok"}' test。若是$1大於100則打印$1 bad,不然打印ok。
$ awk '{if ($1 > 100){ count++; print $1} else {count--; print $2}' test。若是$1大於100,則count加一,並打印$1,不然count減一,並打印$1。
awk有三種循環: while循環;for循環;special for循環。
$ awk '{ i = 1; while ( i <= NF ) { print NF,$i; i++}}' test。變量的初始值爲1,若i小於可等於NF(記錄中域的個數),則執行打印語句,且i增長1。直到i的值大於NF.
$ awk '{for (i = 1; i<NF; i++) print NF,$i}' test。做用同上。
bread continue 語句。break用於在知足條件的狀況下跳出循環;continue用於在知足條件的狀況下忽略後面的語句,直接返回循環的頂端。如:
{for ( x=3; x<=NF; x++) if ($x<0){print "Bottomed out!"; break}} {for ( x=3; x<=NF; x++) if ($x==0){print "Get next item"; continue}}
next 語句從輸入文件中讀取一行,而後從頭開始執行awk腳本。如:
{if ($1 ~/test/){next} else {print} }
exit 語句用於結束awk程序,但不會略過END塊。退出狀態爲0表明成功,非零值表示出錯。
awk中的數組的下標能夠是數字和字母,稱爲關聯數組。
用變量做爲數組下標。如:$ awk {name[x++]=$2};END{for(i=0;i<NR;i++) print i,name[i]}' test。數組name中的下標是一個自定義變量x,awk初始化x的值爲0,在每次使用後增長1。第二個域的值被賦給name數組的各個元素。在END模塊中,for循環被用於循環整個數組,從下標爲0的元素開始,打印那些存儲在數組中的值。由於下標是關健字,因此它不必定從0開始,能夠從任何值開始。
special for 循環用於讀取關聯數組中的元素。格式以下:
{for (item in arrayname){ print arrayname[item] } }$ awk '/^tom/{name[NR]=$1}; END{for(i in name){print name[i]}}' test。打印有值的數組元素。打印的順序是隨機的。
用字符串做爲下標。如:count["test"]
用域值做爲數組的下標。一種新的for循環方式,for (index_value in array) statement。如:$ awk '{count[$1]++} END{for(name in count) print name,count[name]}' test。該語句將打印$1中字符串出現的次數。它首先以第一個域做數組count的下標,第一個域變化,索引就變化。
delete 函數用於刪除數組元素。如:$ awk '{line[x++]=$1} END{for(x in line) delete(line[x])}' test。分配給數組line的是第一個域的值,全部記錄處理完成後,special for循環將刪除每個元素。
sub 函數匹配記錄中最大、最靠左邊的子字符串的正則表達式,並用替換字符串替換這些字符串。若是沒有指定目標字符串就默認使用整個記錄。替換隻發生在第一次匹配的時候。格式以下:
sub (regular expression, substitution string): sub (regular expression, substitution string, target string)
實例:
$ awk '{ sub(/test/, "mytest"); print }' testfile $ awk '{ sub(/test/, "mytest"); $1}; print }' testfile
第一個例子在整個記錄中匹配,替換隻發生在第一次匹配發生的時候。如要在整個文件中進行匹配須要用到gsub
第二個例子在整個記錄的第一個域中進行匹配,替換隻發生在第一次匹配發生的時候。
gsub 函數做用如sub,但它在整個文檔中進行匹配。格式以下:
gsub (regular expression, substitution string) gsub (regular expression, substitution string, target string)
實例:
$ awk '{ gsub(/test/, "mytest"); print }' testfile $ awk '{ gsub(/test/, "mytest" , $1) }; print }' testfile
第一個例子在整個文檔中匹配test,匹配的都被替換成mytest。
第二個例子在整個文檔的第一個域中匹配,全部匹配的都被替換成mytest。
index 函數返回子字符串第一次被匹配的位置,偏移量從位置1開始。格式以下:
index(string, substring)
實例:
$ awk '{ print index("mytest", "test") }' testfile
實例返回test在mytest的位置,結果應該是3。
length 函數返回記錄的字符數。格式以下:
length( string ) length
實例:
$ awk '{ print length( "test" ) }' $ awk '{ print length }' testfile
第一個實例返回test字符串的長度。
第二個實例返回testfile文件中第條記錄的字符數。
substr 函數返回從位置1開始的子字符串,若是指定長度超過實際長度,就返回整個字符串。格式以下:
substr( string, starting position ) substr( string, starting position, length of string )
實例:
$ awk '{ print substr( "hello world", 7,11 ) }'
上例截取了world子字符串。
match 函數返回在字符串中正則表達式位置的索引,若是找不到指定的正則表達式則返回0。match函數會設置內建變量RSTART爲字符串中子字符串的開始位置,RLENGTH爲到子字符串末尾的字符個數。substr可利於這些變量來截取字符串。函數格式以下:
match( string, regular expression )
實例:
$ awk '{start=match("this is a test",/[a-z]+$/); print start}' $ awk '{start=match("this is a test",/[a-z]+$/); print start, RSTART, RLENGTH }'
第一個實例打印以連續小寫字符結尾的開始位置,這裏是11。
第二個實例還打印RSTART和RLENGTH變量,這裏是11(start),11(RSTART),4(RLENGTH)。
toupper 和tolower 函數可用於字符串大小間的轉換,該功能只在gawk中有效。格式以下:
toupper( string ) tolower( string )
實例:
$ awk '{ print toupper("test"), tolower("TEST") }'
split 函數可按給定的分隔符把字符串分割爲一個數組。若是分隔符沒提供,則按當前FS值進行分割。格式以下:
split( string, array, field separator ) split( string, array )
實例:
$ awk '{ split( "20:18:00", time, ":" ); print time[2] }'
上例把時間按冒號分割到time數組內,並顯示第二個數組元素18。
systime函數返回從1970年1月1日開始到當前時間(不計閏年)的整秒數。格式以下:
systime()
實例:
$ awk '{ now = systime(); print now }'
strftime函數使用C庫中的strftime函數格式化時間。格式以下:
systime( [format specification][,timestamp] )
Table 3. 日期和時間格式說明符
格式 | 描述 |
---|---|
%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) |
%% | 百分號(%) |
實例:
$ awk '{ now=strftime( "%D", systime() ); print now }' $ awk '{ now=strftime("%m/%d/%y"); print now }'
如何把一行豎排的數據轉換成橫排?
awk '{printf("%s,",$1)}' filename
http://blog.sina.com.cn/s/blog_5a3640220100b7c8.html
http://www.linuxidc.com/Linux/2012-05/61174.htm
通常在awk裏面輸入文件是多個時,NR==FNR纔有意義,若是這個值爲true,表示還在處理第一個文件。
NR==FNR 這個通常用於讀取兩個或者兩個以上的文件中,用於判斷是在讀取第一個文件。。
test.txt 10行內容
test2.txt 4行內容
awk '{print NR,FNR}' test.txt test2.txt
1 1
2 2
3 3
4 4
5 5
6 6
7 7
8 8
9 9
10 10
11 1
12 2
13 3
14 4
如今有兩個文件格式以下:
#cat account
張三|000001
李四|000002
#cat cdr
000001|10
000001|20
000002|30
000002|15
想要獲得的結果是將用戶名,賬號和金額在同一行打印出來,以下:
張三|000001|10
張三|000001|20
李四|000002|30
李四|000002|15
執行以下代碼
#awk -F \| 'NR==FNR{a[$2]=$0;next}{print a[$1]"|"$2}' account cdr
註釋:
由NR=FNR爲真時,判斷當前讀入的是第一個文件account,而後使用{a[$2]=$0;next}循環將account文件的每行記錄都存入數組a,並使用$2第2個字段做爲下標引用.
由NR=FNR爲假時,判斷當前讀入了第二個文件cdr,而後跳過{a[$2]=$0;next},對第二個文件cdr的每一行都無條件執行 {print a[$1]"|"$2},此時變量$1爲第二個文件的第一個字段,與讀入第一個文件時,採用第一個文件第二個字段$2爲數組下標相同.所以能夠在此使用 a[$1]引用數組。
awk '{gsub(/\$/,"");gsub(/,/,"");
if ($1>=0.1 && $1<0.2) c1+=1;
else if ($1>=0.2 && $1<0.3) c2+=1;
else if ($1>=0.3 && $1<0.4) c3+=1;
else if ($1>=0.4 && $1<0.5) c4+=1;
else if ($1>=0.5 && $1<0.6) c5+=1;
else if ($1>=0.6 && $1<0.7) c6+=1;
else if ($1>=0.7 && $1<0.8) c7+=1;
else if ($1>=0.8 && $1<0.9) c8+=1;
else if ($1>=0.9 ) c9+=1;
else c10+=1; }
END {printf "%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t",c1,c2,c3,c4,c5,c6,c7,c8,c9,c10} ' /NEW
示例/例子:
awk '{if($0~/^>.*$/) {tmp=$0; getline; if( length($0)>=200) {print tmp"\n"$0; } }}' filename
awk '{if($0~/^>.*$/) {IGNORECASE=1; if($0~/PREDICTED/) {getline;} else {print $0; getline; print $0; } }}' filename
awk '{if($0~/^>.*$/) {IGNORECASE=1; if($0~/mRNA/) {print $0; getline; print $0; } else {getline;} }}' filename
awk '{ temp=$0; getline; if($0~/unavailable/) {;} else {print temp"\n"$0;} }' filename
substr($4,20) ---> 表示是從第4個字段裏的第20個字符開始,一直到設定的分隔符","結束.
substr($3,12,8) ---> 表示是從第3個字段裏的第12個字符開始,截取8個字符結束.
1、awk字符串轉數字
$ awk 'BEGIN{a="100";b="10test10";print (a+b+0);}'
110
只須要將變量經過」+」鏈接運算。自動強制將字符串轉爲整型。非數字變成0,發現第一個非數字字符,後面自動忽略。
2、awk數字轉爲字符串
$ awk 'BEGIN{a=100;b=100;c=(a""b);print c}'
100100
只須要將變量與」」符號鏈接起來運算便可。
3、awk字符串鏈接操做(字符串鏈接;連接;串聯)
$ awk 'BEGIN{a="a";b="b";c=(a""b);print c}'
ab
$ awk 'BEGIN{a="a";b="b";c=(a+b);print c}'
0
把文件中的各行串聯起來:
awk 'BEGIN{xxxx="";}{xxxx=(xxxx""$0);}END{print xxxx}' temp.txt
awk 'BEGIN{xxxx="";}{xxxx=(xxxx"\",\""$0);}END{print xxxx}' temp.txt
提取知足條件的子字符串:
cat > temp
74938 A>G 347589B>C43795743
awk '{x=$0;while (match(x, "[A-Z]>[A-Z]") > 0) { print substr(x, RSTART, RLENGTH); x = substr(x, RSTART+RLENGTH);} }' temp
awk字符串函數,包含使用示例:
https://www.tutorialspoint.com/awk/awk_string_functions.htm
https://www.gnu.org/software/gawk/manual/html_node/String-Functions.html