天天看點

Linux系統開發: 學習linux三劍客(awk、sed、grep)(下)

一、前言

這篇文章是 <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

Linux系統開發: 學習linux三劍客(awk、sed、grep)(下)
$ awk  'BEGIN{a="b"; print a++,++a}'  #注意這裡a="b"後面一定要加;,表明這是一條語句。      

2.2.2 指派運算符

Linux系統開發: 學習linux三劍客(awk、sed、grep)(下)

2.2.3 關系運算符

注意:> < 可以作為字元串比較,也可以用作數值比較,關鍵看操作數如果是字元串就會轉換為字元串比較。兩個都為數字才轉為數值比較。字元串比較:按照ASCII碼順序比較。

Linux系統開發: 學習linux三劍客(awk、sed、grep)(下)

2.2.4 邏輯運算符

Linux系統開發: 學習linux三劍客(awk、sed、grep)(下)
$ awk  'BEGIN{a=1;b=2;print (a>5 && b<=2),(a>5 || b<=2);}'

0 1      

2.2.5 正則運算符

Linux系統開發: 學習linux三劍客(awk、sed、grep)(下)

需用到正規表達式/^.../,表示以什麼内容開頭的

$ 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 其他運算符

Linux系統開發: 學習linux三劍客(awk、sed、grep)(下)
$ 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 運算符優先級表

Linux系統開發: 學習linux三劍客(awk、sed、grep)(下)

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 算術函數

Linux系統開發: 學習linux三劍客(awk、sed、grep)(下)

2.5.2 字元串函數

注:Ere都可以是正規表達式。

請參考常用示例。

Linux系統開發: 學習linux三劍客(awk、sed、grep)(下)

這裡注意sprintf格式化字元串輸出

其中格式化字元串包括兩部分内容:一部分是正常字元,這些字元将按原樣輸出; 另一部分是格式化規定字元,以"%"開始,後跟一個或幾個規定字元,用來确定輸出内容格式。

2.5.3 格式符清單

Linux系統開發: 學習linux三劍客(awk、sed、grep)(下)
$ 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 一般函數

Linux系統開發: 學習linux三劍客(awk、sed、grep)(下)

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 時間函數

Linux系統開發: 學習linux三劍客(awk、sed、grep)(下)

strftime日期和時間格式說明符

Linux系統開發: 學習linux三劍客(awk、sed、grep)(下)

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秒      

繼續閱讀