一、前言
這篇文章是 <Linux開發: 學習linux三劍客(awk、sed、grep)(上)>的續集。
二、awk指令
2.1 awk指令基本使用介紹
awk是它的三個作者姓氏的首字母合寫,他們是:Aho(阿爾佛雷德·艾侯)、Winberger(彼得·溫伯格)和Kernighan(布萊恩·柯林漢),他們三人合著《AWK程式設計》。
awk是一種文本處理工具,同時它也是一門微型程式設計語言,它的目的是編寫小巧 但充滿表達力的程式,把文本的輸入變換為文本的輸出。用于在linux/unix下對文本和資料進行處理。資料可以來自标準輸入(stdin)、一個或多個檔案,或其它指令的輸出。它支援使用者自定義函數和動态正規表達式等先進功能,是linux/unix下的一個強大程式設計工具。它在指令行中使用,但更多是作為腳本來使用。awk有很多内建的功能,比如數組、函數等,這是它和C語言的相同之處,靈活性是awk最大的優勢。
現今的Linux發行版所附帶的awk實際上很新,是GNU的重寫版本,也叫GNU awk,程式名是gawk。
awk指令格式和選項、文法形式:
awk [options] 'script' var=value file(s)
awk [options] -f scriptfile var=value file(s)
常用選項:
-F fs fs指定輸入分隔符,fs可以是字元串或正規表達式,如-F:
-v var=value 指派一個使用者定義變量,将外部變量傳遞給awk
-f scripfile 從腳本檔案中讀取awk指令
-m[fr] val 對val值設定内在限制,-mf選項限制配置設定給val的最大塊數目;-mr選項限制記錄的最大數目。這兩個功能是Bell實驗室版awk的擴充功能,在标準awk中不适用
awk的核心思想是模式和行為操作,也叫模式驅動程式設計。模式一般是關系或正規表達式,用于與輸入的每條記錄進行比對;而行為操作則是對模式比對到的記錄的處理方法,采用與C類似的文法,并由一對大括号“{}”括起來。
模式
/正規表達式/:使用通配符的擴充集。
關系表達式:使用運算符進行操作,可以是字元串或數字的比較測試。
模式比對表達式:用運算符~(比對)和~!(不比對)。
BEGIN語句塊、pattern語句塊、END語句塊
行為操作
操作由一個或多個指令、函數、表達式組成,之間由換行符或分号隔開,并位于大括号内,主要部分是:
變量或數組指派
輸出指令
内置函數
控制流語句
awk腳本基本結構
awk 'BEGIN{ commands } pattern{ commands } END{ commands }' file
一個awk腳本通常由:BEGIN語句塊、能夠使用模式比對的通用語句塊、END語句塊3部分組成,這三個部分是可選的。任意一個部分都可以不出現在腳本中,腳本通常是被單引号或雙引号中。
示例:
例如:
awk 'BEGIN{ i=0 } { i++ } END{ print i }' filename
awk "BEGIN{ i=0 } { i++ } END{ print i }" filename
awk的工作原理
第一步:執行BEGIN{ commands }語句塊中的語句;
第二步:從檔案或标準輸入(stdin)讀取一行,然後執行pattern{ commands }語句塊,它逐行掃描檔案,從第一行到最後一行重複這個過程,直到檔案全部被讀取完畢。
第三步:當讀至輸入流末尾時,執行END{ commands }語句塊。
BEGIN語句塊在awk開始從輸入流中讀取行之前被執行,這是一個可選的語句塊,比如變量初始化、列印輸出表格的表頭等語句通常可以寫在BEGIN語句塊中。
END語句塊在awk從輸入流中讀取完所有的行之後即被執行,比如列印所有行的分析結果這類資訊彙總都是在END語句塊中完成,它也是一個可選語句塊。
pattern語句塊中的通用指令是最重要的部分,它也是可選的。如果省略模式,則行為将被應用到每條輸入記錄;如果省略行為,則預設操作是在标準輸出上列印比對到的記錄,執行{ print }。
awk程式的pattern語句塊有以下三種情況:
awk 'pattern {commands }' #如果模式比對,則執行行為
awk 'pattern ' #如果模式比對,則在标準輸出上列印記錄執行{ print }
awk ' {commands }' # 針對每條記錄,執行行為。
$ echo -e "hello \n my baymax " | awk 'BEGIN{ print "Start" } { print } END{ print "End" }' #完整的結構
#-e參數表示echo内可使用轉義字元
$ echo -e "hello \n my baymax " | awk 'BEGIN{ print "Start" } { print } ' #省略end結構
$ echo -e "hello \n my baymax " | awk ' { print } ' #省略前後結構
$ echo -e "hello \n my baymax " | awk ' { print } END{ print "End" }' #省略begin結構
當使用不帶參數的print時,它就列印目前行,當print的參數是以逗号進行分隔時,列印時則以空格作為定界符。例如:
$echo | awk '{ var1="v1"; var2="v2"; var3="v3"; print var1,var2,var3; }'
v1 v2 v3
在awk的print語句塊中雙引号是被當作拼接符使用:
echo | awk '{ var1="v1"; var2="v2"; var3="v3"; print var1"="var2"="var3; }'
v1=v2=v3
{ }類似一個循環體,會對檔案中的每一行進行疊代,通常變量初始化語句(如:i=0)以及列印檔案頭部的語句放入BEGIN語句塊中,将列印的結果等語句放在END語句塊中。
awk内置變量(預定義變量)
說明:[A][N][P][G]表示第一個支援變量的工具,[A]=awk、[N]=nawk、[P]=POSIXawk、[G]=gawk
$n 目前記錄的第n個字段,比如n為1表示第一個字段,n為2表示第二個字段。 字段是用空格隔開的單詞段。
$0 這個變量包含執行過程中目前行的文本内容。
[A] NF 表示字段數,在執行過程中對應于目前的字段數。而$NF則表示一行中的最後一個字段。$(NF-n)則表示一行中的倒數第n個字段,n為正整數。
[A] NR 表示記錄數,在執行過程中對應于目前的行号。
[A] OFMT 數字的輸出格式(預設值是%.6g)。
[A] OFS 輸出字段分隔符(預設值是一個空格)。
[A] ORS 輸出記錄分隔符(預設值是一個換行符)。
[A] RS 記錄分隔符(預設是一個換行符)。
[A] FILENAME 目前輸入檔案的名。
[A] FS 字段分隔符(預設是任何空格)。
[G] ARGIND 指令行中目前檔案的位置(從0開始算)。
[G] CONVFMT 數字轉換格式(預設值為%.6g)。
[G] FIELDWIDTHS 字段寬度清單(用空格鍵分隔)。
[G] IGNORECASE 如果為真,則進行忽略大小寫的比對。
[N] RSTART 由match函數所比對的字元串的第一個位置。
[N] RLENGTH 由match函數所比對的字元串的長度。
[N] SUBSEP 數組下标分隔符(預設值是34)。
[N] ARGV 包含指令行參數的數組。
[N] ARGC 指令行參數的數目。
[N] ERRNO 最後一個系統錯誤的描述。
[P] ENVIRON 環境變量關聯數組。
[P] FNR 同NR,但相對于目前檔案。
需用到内置變量:NR 表示記錄數,在執行過程中對應于目前的行号。
需用到内置變量:NF 表示字段數,在執行過程中對應于目前的字段數。而$NF則表示一行中的最後一個字段。
需用到内置變量:$n 目前記錄的第n個字段,比如n為1表示第一個字段,n為2表示第二個字段。
$ echo -e "line1 f2 f3\n line2 f4 f5" | awk '{print "Line No:"NR", No of fields:"NF, "$0="$0, "$1="$1, "$2="$2, "$3="$3}'
将外部變量值傳遞給awk
需用到-v選項,可以将外部值(并非來自stdin)傳遞給awk,有三種方式。
第一種:寫在腳本内(腳本字尾名随意,編輯好直接運作即可)
var1="aaa"
var2="bbb"
echo | awk '{ print v1,v2 }' v1=$var1 v2=$var2
第二種:傳遞外部變量方法:
Va=100
echo | awk -v VARIABLE=$Va '{ print VARIABLE }'
第三種:當輸入來自于檔案時使用??
awk '{ print v1,v2 }' v1=$var1 v2=$var2 filename
以上方法中,變量之間用空格分隔作為awk的指令行參數跟随在BEGIN、{}和END語句塊之後。
2.2 awk運算符
awk支援多種運算,這些運算與C語言提供的基本相同。awk還提供了一系列内置的運算函數(如log、sqr、cos、sin等)和一些用于對字元串進行操作(運算)的函數(如length、substr等等)。這些函數的引用大大的提高了awk的運算功能。作為對條件轉移指令的一部分,關系判斷是每種程式設計語言都具備的功能,awk也不例外,awk中允許進行多種測試,作為樣式比對,還提供了模式比對表達式~(比對)和~!(不比對)。作為對測試的一種擴充,awk也支援用邏輯運算符。
2.2.1 算術運算符
注意:所有用作算術運算符進行操作,操作數自動轉為數值,所有非數值都變為0
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLicmbw5yYmJjZjJTO4YjMmlzM5QTYxQWZ0ATMwQmMlZTO1UGMm9CX5d2bs92Yl1iclB3bsVmdlR2LcNWaw9CXt92Yu4GZjlGbh5yYjV3Lc9CX6MHc0RHaiojIsJye.png)
$ awk 'BEGIN{a="b"; print a++,++a}' #注意這裡a="b"後面一定要加;,表明這是一條語句。
2.2.2 指派運算符
2.2.3 關系運算符
注意:> < 可以作為字元串比較,也可以用作數值比較,關鍵看操作數如果是字元串就會轉換為字元串比較。兩個都為數字才轉為數值比較。字元串比較:按照ASCII碼順序比較。
2.2.4 邏輯運算符
$ awk 'BEGIN{a=1;b=2;print (a>5 && b<=2),(a>5 || b<=2);}'
0 1
2.2.5 正則運算符
需用到正規表達式/^.../,表示以什麼内容開頭的
$ awk 'BEGIN{a="100testa";if(a ~ /^100*/) {print "ok";}}'
ok
$ awk 'BEGIN{a="100testa";if(a !~ /^100*/){print "ok";}else {print "error"}}'
error
2.2.6 其他運算符
$ awk 'BEGIN{a="b";arr[0]="b";arr[1]="c";print (b in arr);}' #b in arr問arr是否有b這個下标0
$ awk 'BEGIN{b=0;arr[0]="b";arr[1]="c";print (b in arr);}' #b最初指派為1,而數組arr下标為1是存在的1
2.2.7 運算符優先級表
2.3 制語句
在linux awk的while、do-while和for語句中允許使用break,continue語句來控制流程走向,也允許使用exit這樣的語句來退出。break中斷目前正在執行的循環并跳到循環外執行下一條語句。if 是流程選擇用法。每條指令語句後面可以用;分号結尾。
2.3.1 if條件判斷語句
文法:表達式為真執行語句1,為假執行語句2
if(表達式)
語句1
else
語句2
格式中語句1可以是多個語句,為了友善判斷和閱讀,最好将多個語句用{}括起來。awk分枝結構允許嵌套,其格式為:
if(表達式)
{語句1}
else if(表達式)
{語句2}
else
{語句3}
編寫在腳本内
$ cat ass.sh
awk 'BEGIN{
test=100;
if(test>90){
print "very good";
}
else if(test>60){
print "good";
}
else{
print "no pass";
}
}'
輸出結果:very good
2.3.2 while循環語句
文法:表達式為真,循環執行語句,直到條件為假
while(表達式)
{語句}
2.3.3 do...while循環語句
文法:先執行語句再判斷條件真假,為真則循環執行,為假停止執行。
do
{語句} while(條件)
2.3.4 for循環語句
文法一:執行變量初始化,再判斷條件,條件為真,執行語句,再執行表達式,再判斷條件,條件為真,再執行語句,如此循環直至條件為假。
for(變量初始化;條件;表達式)
{語句}
文法二:每次從數組中取一個值賦給變量,再執行語句,循環直到數組内部的資料取完,變量為空。
for(變量 in 數組)
{語句}
需用内置變量ENVIRON :目前系統環境變量關聯數組
[DSYU@DSYU shell]$ cat ass.sh
awk 'BEGIN{
for(k in ENVIRON){
print k"="ENVIRON[k];
}
}'
#每次從環境變量數組中取一個資料指派給k,然後再列印出來。
2.3.5 ext語句
next 能夠導緻讀入下一個輸入行,并傳回到腳本的頂部。這可以避免對目前輸入行執行其他的操作過程。
awk中next語句使用:在循環逐行比對,如果遇到next,就會跳過目前行,直接忽略下面語句。而進行下一行比對。next語句一般用于多行合并:
需用到内置變量NR:表示記錄數,在執行過程中對應于目前的行号
$ awk 'NR%2==1{next}{print NR,$0;}' 123.txt #表示當行号取餘2為1也就是奇數行時跳過目前行
2.3.6 其他語句
break 當 break 語句用于 while 或 for 語句時,導緻退出程式循環。
continue 當 continue 語句用于 while 或 for 語句時,使程式循環移動到下一個疊代。
exit 語句使主輸入循環退出并将控制轉移到END,如果END存在的話。如果沒有定義END規則,或在END中應用exit語句,則終止腳本的執行。
2.4 數組的運用
數組是awk的靈魂,處理文本中最不能少的就是它的數組處理。因為數組索引(下标)可以是數字和字元串,在awk中數組叫做關聯數組(associative arrays)。awk 中的數組不必提前聲明,也不必聲明大小。數組元素用0或空字元串來初始化,這根據上下文而定。因為數組是關聯數組,預設是無序的。是以通過for…in得到是無序的數組。如果需要得到有序數組,需要通過指定下标獲得。
2.4.1 數組的定義
awk的數組不必提前聲明,也不必聲明大小。
數字做數組索引(下标或鍵值)。
注意:數組下标是從1開始,與C數組不一樣。
Array[1]="sun"
Array[2]=1970
字元串做數組索引(下标):
Array["first"]="year"
Array["birth"]="1970"
使用中print Array[1]會列印出sun;使用print Array[2]會列印出1970;使用print["first"]會得到year。
$ awk 'BEGIN {Array["first"]="year"; Array[2]=1970; {print Array["first"]"="Array[2]}}'
year=1970
$ awk 'BEGIN {Array["first"]="year"; Array[2]=1970; { for(item in Array) {print Array[item],item}; }}'
year first
1970 2
#注意此處是取的數組的下标值賦給item,而不是數組元素值
2.4.2 數組函數
length函數
使用形式:length(array)
length函數傳回array數組長度,array可是數組名也可使字元串。
$ awk 'BEGIN { print length("hello")}'
5
split函數
使用形式:split(src,dst,accrod);
split函數以accrod為依據分割src字元串為數組存儲到dst内,也會傳回分割得到數組長度。
$ awk 'BEGIN{info="it is a test 56 78";lens=split(info,tA,"is");print lens,tA[1],tA[2],tA[3]}'
#此示例以is為依據分隔info,分隔為為兩個字元串,是以lens為2。
$ awk 'BEGIN{info="it is a test 56 78";lens=split(info,tA,"");print lens,tA[1],tA[2],tA[3]}'
#此示例是把info字元串内的所有字元拆分為獨立的單個字元存儲到tA數組中。
asort函數
使用形式:asort(array);不能對字元串操作。
對array數組進行排序,傳回數組長度(下标的個數而不是字元的個數)。
$ awk 'BEGIN{info[1]="it";info[2]="aa";{print asort(info),info[1],info[2]}}'
#此示例對info數組排序,傳回數組元素個數。
delete
使用形式:delete array[key],可以删除對應數組array key的序列值。
if(key in array)通過這種方法判斷數組中是否包含
key
鍵值。
$ awk 'BEGIN{tB["a"]="a1";tB["b"]="b1";delete tB["b"];for(k in tB){print k,tB[k];}}'
a a1
2.4.3 二維、多元數組使用
awk的多元數組在本質上是一維數組,更确切一點,awk在存儲上并不支援多元數組。awk提供了邏輯上模拟二維數組的通路方式。例如,array[2,4]=1這樣的通路是允許的。
類似一維數組的成員測試,多元數組可以使用if ( (i,j) in array)這樣的文法,但是下标必須放置在圓括号中。類似一維數組的循環通路,多元數組使用for ( item in array )這樣的文法周遊數組。與一維數組不同的是,多元數組必須使用split()函數來通路單獨的下标,awk使用一個特殊的字元串SUBSEP作為分割字段。
可以通過array[k,k2]引用獲得數組内容。
awk 'BEGIN{
for(i=1;i<=9;i++){
for(j=1;j<=9;j++){
tarr[i,j]=i*j; print i,"*",j,"=",tarr[i,j];
}
}
}'
另一種方式:
awk 'BEGIN{
for(i=1;i<=9;i++){
for(j=1;j<=9;j++){
tarr[i,j]=i*j;
}
}
for(m in tarr){
split(m,tarr2,SUBSEP); print tarr2[1],"*",tarr2[2],"=",tarr[m];
}
}'
# split(m,tarr2,SUBSEP); 運用了SUBSEP特殊字元串,把二維數組的鍵值m分割存放在tarr2數組中。
2.5 内置函數
awk内置函數,主要分以下:算數函數、字元串函數、其它一般函數、時間函數。
2.5.1 算術函數
2.5.2 字元串函數
注:Ere都可以是正規表達式。
請參考常用示例。
這裡注意sprintf格式化字元串輸出
其中格式化字元串包括兩部分内容:一部分是正常字元,這些字元将按原樣輸出; 另一部分是格式化規定字元,以"%"開始,後跟一個或幾個規定字元,用來确定輸出内容格式。
2.5.3 格式符清單
$ 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, 1,1.2345,7C,174
2.6 一般函數
getline函數
awk getline用法:輸出重定向需用到getline函數。getline從标準輸入、管道或者目前正在處理的檔案之外的其他輸入檔案獲得輸入。它負責從輸入獲得下一行的内容,并給NF,NR和FNR等内建變量指派。
如果得到一條記錄,getline函數傳回1,如果到達檔案的末尾就傳回0,如果出現錯誤,例如打開檔案失敗,就傳回-1。
getline文法:getline var,變量var包含了特定行的内容。
awk getline從整體上來說,用法說明:
當其左右無重定向符|或<時:getline作用于目前檔案,讀入目前檔案的第一行給其後跟的變量var或$0(無變量),應該注意到,由于awk在處理getline之前已經讀入了一行,是以getline得到的傳回結果是隔行的。
當其左右有重定向符|或<時:getline則作用于定向輸入檔案,由于該檔案是剛打開,并沒有被awk讀入一行,隻是getline讀入,那麼getline傳回的是該檔案的第一行,而不是隔行。
執行linux的date指令,并通過管道輸出給getline,然後再把輸出指派給自定義變量out,并列印它:
awk 'BEGIN{ "date" | getline out; print out }' test
執行shell的date指令,并通過管道輸出給getline,然後getline從管道中讀取并将輸入指派給out,
split函數把變量out轉化成數組mon,然後列印數組mon的第二個元素:
awk 'BEGIN{ "date" | getline out; split(out,mon); print mon[2] }' test
指令
ls的輸出傳遞給geline作為輸入,循環使getline從ls的輸出中讀取一行,并把它列印到螢幕。這裡沒有輸入檔案,因為BEGIN塊在打開輸入檔案前執行,是以可以忽略輸入檔案。
awk 'BEGIN{ while( "ls" | getline) print }'
2.7 檔案操作
關閉檔案
awk中允許在程式中關閉一個輸入或輸出檔案,方法是使用awk的close。
close("filename")
filename可以是getline打開的檔案,也可以是stdin,包含檔案名的變量或者getline使用的确切指令。或一個輸出檔案,可以是stdout,包含檔案名的變量或使用管道的确切指令。
輸出到一個檔案
awk中允許用如下方式将結果輸出到一個檔案:
echo | awk '{printf("hello word!n") > "datafile"}'
或
echo | awk '{printf("hello word!n") >> "datafile"}'
2.8 時間函數
strftime日期和時間格式說明符
2.9 設定字段定界符
預設的字段定界符是空格,可以使用
-F "定界符"
明确指定一個定界符:
awk -F: '{ print $NF }' /etc/passwd
或
awk 'BEGIN{ FS=":" } { print $NF }' /etc/passwd
在
BEGIN語句塊
中則可以用
OFS=
“定界符”
設定輸出字段的定界符。
2.10 常用示例
2.10.1 列印每一行内容
需用到内置變量:$0 這個變量包含執行過程中目前行的文本内容。
$ awk '{print $0}' 123.txt
$ awk '{print }' 123.txt
2.10.2 列印每一行的前面字段
$ awk '{print $1,$2}' 123.txt
2.10.3 列印每一行的最後字段
需用到内置變量:$NF表示一行的最後一個字段,
需用到内置變量:$(NF-n)表示一行中的倒數第幾個字段,
$ awk '{print $NF}' 123.txt
$ awk '{print $(NF-1)}' 123.txt
2.10.4 列印文本總行數
需用到内置變量: NR 表示記錄數,在執行過程中對應于目前的行号。
$ awk END'{print NR}' 123.txt #注意此處要用END語句塊,如果用通用,則會列印每一行的行号,而END隻會列印最後一次的行号,也就是總的行數
2.10.5 算術運算求冥
需用到算術運算符**與^,都表示求冥
$ awk ' BEGIN{print 3**3}' #隻有BEGIN語句塊,不用輸入檔案
$ echo | awk ' END{print 3**3}' #有END語句塊,必須有輸入檔案,這裡用echo輸入一個空字元串
$ echo | awk '{print 3^3} ' #有通用語句塊,必須有輸入檔案
2.10.6 跳過某行
需運用到next語句,表示跳過目前行
需用到正規表達式/...$/,$表明以某内容結尾的
$ awk '/sh$/{next}{print $0}' 123.txt #直接跳過以sh結尾的行
2.10.7 判斷關聯數組中是否存在某鍵值
$ awk 'BEGIN{tB["a"]="a1";tB["b"]="b1";if( "c" in tB){print "ok";}else {print "no"};}'
no
2.10.8 循環列印數組元素
$ awk 'BEGIN{tB["a"]="a1";tB["b"]="b1";for(k in tB){print k,tB[k];}}'
2.10.9 替換指定字元串
需用到字元串函數:gsub( Ere, Repl, [ In ] ),替換所有與正規表達式相比對的具體值
需用到字元串函數:sub( Ere, Repl, [ In ] ),替換第一個與正規表達式相比對的具體值
需用到正規表達式:[-],表明比對範圍内的任意字元,[0-9]表明比對0-9的任意數字
需用到正規表達式:+,表明比對之前的項一次或多次
注意正規表達式需用//括起來。
$ awk 'BEGIN{info="this is a test2010test!2008";gsub(/[0-9]+/,"!",info);print info}'
this is a test!test!!
[DSYU@DSYU shell]$ awk 'BEGIN{info="this is a test2010test!2008";sub(/[0-9]+/,"!",info);print info}'
this is a test!test!2008
2.10.10 指定字元串查找
需用到字元串函數:index( Str1, Str2 ),在str1中尋找str2,有即傳回位置(從1開始),沒有傳回0.
需用到其他運算符:?: ;a?b:c; a為真則b為整個表達式結果,否則c為整個表達式結果。
$ awk 'BEGIN{info="this is a test2010test!";print index(info,"tast")?"ok":"not found";}'
not found
$ awk 'BEGIN{info="this is a test2010test!";print index(info,"test")?"ok":"no found";}'
ok
$ awk 'BEGIN{info="this is a test2010test!";print len=index(info,"test");}'
2.10.11 指定正規表達式比對查找
需用到字元串函數:match( Str, Ere );成功傳回在str中能比對ERe正規表達式的位置,沒有傳回0.
$ $ awk 'BEGIN{info="this is a test2010test!";len=match(info,/[0-9]+/);print len}'
15
$ awk 'BEGIN{info="this is a test2010test!";len=match(info,/[5-9]+/);print len}'
0
2.10.12 截取字元串
需用到字元串函數:substr( String, M, [ N ] ),傳回從string指定字元串第M個位置(編号從1開始)截取的N個字元組成的字元串。未指定N,則傳回M位置到最末尾。
$ awk 'BEGIN{info="this is a test2010test!";print substr(info,4,10)}'
s is a tes
[DSYU@DSYU shell]$ awk 'BEGIN{info="this is a test2010test!";print substr(info,4)}'
s is a test2010test!
2.10.13 字元串分割
需用到字元串函數:split( String, A, [Ere] ),将 String 參數指定的參數以ERe指定的依據為準分割為數組元素 A[1], A[2], . . ., A[n],并傳回 n 變量的值。
$ 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
2.10.14 打開外部檔案
需用到一般函數:Expression | getline [ Variable ],從來自 Expression 參數指定的指令的輸出中通過管道傳送的流中讀取一個輸入記錄,并将該記錄的值指定給 Variable 參數指定的變量。
需用到一般函數:close( Expression ),用同一個帶字元串值的 Expression 參數來關閉由 print 或 printf 語句打開的或調用 getline 函數打開的檔案或管道。
$ awk 'BEGIN{while("cat /etc/passwd"|getline){print $0;};close("/etc/passwd");}'
2.10.15 擷取輸入資訊
需用到一般函數:getline [ Variable ] file ,讀取file内的一行資訊存儲到Variable 内。如果未指定file,預設從标準輸入檔案中讀取。
$ awk 'BEGIN{print "Enter your name:";getline name;print name;}'
Enter your name:
yu #此行是使用者輸入的
yu
$ awk 'BEGIN{print "Enter your name:";getline name;print name;}' 123.txt
Enter your name:
8.sh 9.sh 10.bck
2.10.16 建立指定時間
需用到時間函數:mktime( YYYY MM dd HH MM ss[ DST]),生成時間格式,傳回從1970年1月1日開始到指定時間的的整秒數需用到時間函數:strftime([format [, timestamp]]),格式化時間輸出,将時間戳轉為時間字元串具體格式。
$ awk 'BEGIN{tmp=mktime("2006 06 06 6 6 6");print strftime("%c",tmp);}'
2006年06月06日 星期二 06時06分06秒