awk 字符串處理函數


awk提供了許多強大的字符串函數,見下表:

awk內置字符串函數

gsub(r,s)    在整個$0中用s替代r
gsub(r,s,t)     在整個t中用s替代r
index(s,t)     返回s中字符串t的第一位置
length(s)     返回s長度
match(s,r)     測試s是否包含匹配r的字符串
split(str,arr,fs)     split使用域分隔符fs將字符串str划分為指定序列arr。
sprint(fmt,exp)    

返回經fmt格式化后的exp

sprint函數類似於printf函數(以后涉及),返回基本輸出格式fmt的結果字符串exp。

sub(r,s)     用$0中最左邊最長的子串代替s
substr(s,p)     返回字符串s中從p開始的后綴部分
substr(s,p,n)     返回字符串s中從p開始長度為n的后綴部分 詳細說明一下各個函數的使用方法。
gensub(a,b,c[,d]) 全局替換,匹配正則a, 用b替換,c為指定替換目標是第幾次匹配,d為指定替換目標是哪個域如$1,$2,若無d指$0,返回值為target替換后內容(未替換還是返回 target原內容),與sub、gsub不同的是,target內容替換后不改變。
gensub(/123/,"x",1,$1) 替換$1中 第一次匹配到的123為字符x,返回值為$1替換后的內容,且$1的內容並沒有改變
gensub(/a(.*)b/,"\\1",1)  返回值為匹配正則第1對()內的內容
gensub(/a(.*)b(.*)c/,"\\2",1)  返回值為匹配正則第2對()內的內容

 

現在看一看awk中這些字符串函數的功能。

1.gsub

gsub函數有點類似於sed查找和替換。它允許替換一個字符串或字符為另一個字符串或字符,並以正則表達式的形式執行。第一個函數作用於記錄$0,第二個gsub函數允許指定目標,然而,如果未指定目標t,缺省為$0。

要在整個記錄中替換一個字符串為另一個,使用正則表達式格式,/目標模式/,替換模式

/。例如改變學生序號4842到4899:

$ awk 'gsub('4842/, 4899) {print $0}' grade.txt

J.Troll 07/99 4899 Brown-3 12 26 26

 

2.index

index(s,t)函數返回目標字符串s中查詢字符串t的首位置。

查詢字符串s中t出現的第一位置。必須用雙引號將字符串括起來。例如返回目標字符串

Bunny中ny出現的第一位置,即字符個數。

$ awk 'BEGIN {print index("Bunny", "ny")} grade.txt

4

 

3.length

length函數返回字符串s字符長度。

返回所需字符串長度,例如檢驗字符串J.Troll返回名字及其長度,即人名構成的字符個

數。

$ awk '$1=="J.Troll" {print length($1) " "$1}' grade.txt

7 J.Troll

 

還有一種方法,這里字符串加雙引號。

$ awk 'BEGIN {print length("A FEW GOOD MEN")}'

14

 

4.match

match函數測試字符串s是否包含一個正則表達式r定義的匹配。

match測試目標字符串是否包含查找字符的一部分。可以對查找部分使用正則表達式,返

回值為成功出現的字符排列數。如果未找到,返回0,第一個例子在ANCD中查找d。因其不

存在,所以返回0。第二個例子在ANCD中查找D。因其存在,所以返回ANCD中D出現的首位

置字符數。第三個例子在學生J.Lulu中查找u。

$ awk '{BEGIN {print match("ANCD", /d/)}'

0

$ awk '{BEGIN {print match("ANCD", /C/)}'

3

$ awk '$1=="J.Lulu" {print match($1, "u")} grade.txt

4

 

5.split

split使用域分隔符fs將字符串str划分為指定序列arr。

使用split返回字符串數組元素個數。工作方式如下:如果有一字符串,包含一指定分隔

符-,例如AD2-KP9-JU2-LP-1,將之划分成一個數組。使用split,指定分隔符及數組名。此

例中,命令格式為("AD2-KP9-JU2-LP-1",parts_array,"-"),split然后返回數組長度,這

里結果為4。

還有一個例子使用不同的分隔符。

$ awk '{BEGIN {print split("123#456#678", myarray, "#")}'

3

 

這個例子中,split返回數組myarray的下標數。數組myarray取值如下:

Myarray[1]="123"

Myarray[2]="456"

Myarray[3]="789"

 

6.sub

sub(r,s)函數將用s替代$0中最左邊最長的子串,該子串被(r)匹配。

sub(s,p)返回字符串s在位置p后的后綴。substr(s,p,n)同上,並指定子串長度為n。

使用sub發現並替換模式的第一次出現位置。字符串STR包含‘popedpopopill’,執行下

列sub命令sub(/op/,"op",STR)。模式op第一次出現時,進行替換操作,返回結果如下:

‘pOPedpopepill’。

假如grade.txt文件中,學生J.Troll的記錄有兩個值一樣,“目前級別分”與“最高級別分”。只

改變第一個為29,第二個仍為24不動,操作命令為sub(/26/,"29",$0),只替換第一個出現

24的位置。

$ awk '$1=="J.Troll" sub(/26/, "29", $0)' grade.txt

L.Troll 07/99 4842 Brown-3 12 29 26

L.Transley 05/99 4712 Brown-2 12 30 28

 

7.substr

substr是一個很有用的函數。它按照起始位置及長度返回字符串的一部分。例子如下:

$ awk '$1=="L.Transley" {print substr($1, 1,5)}' grade.txt

L.Tan

 

上面例子中,指定在域1的第一個字符開始,返回其前面5個字符。

如果給定長度值遠大於字符串長度, awk將從起始位置返回所有字符,要抽取L.Tansley的姓,只需從第3個字符開始返回長度為7。可以輸入長度99,awk返回結果相同。

$ awk '{$1=="L.Transley" {print substr($1, 3,99)}' grade.txt

Transley

 

substr的另一種形式是返回字符串后綴或指定位置后面字符。這里需要給出指定字符串及其返回字串的起始位置。例如,從文本文件中抽取姓氏,需操作域1,並從第三個字符開始:

$ awk '{print substr($1, 3)}' grade.txt

Troll

Transley

 

還有一個例子,在BEGIN部分定義字符串,在END部分返回從第t個字符開始抽取的子串。

$ awk '{BEGIN STR="A FEW GOOD MEN"} END {print substr(STR,7)) grade.txt

GOOD MEN

 

8.從shell中向awk傳入字符串

awk腳本大多只有一行,其中很少是字符串表示的,這一點通過將變量傳入awk命令行會變得很容易。現就其基本原理講述一些例子。

使用管道將字符串stand-by傳入awk,返回其長度。

$ echo "Stand-by" | awk '{print length($0)}'

8

 

設置文件名為一變量,管道輸出到awk,返回不帶擴展名的文件名。

$ STR="mydoc.txt"

$ echo $STR | awk '{print subst($STR, 1, 5)}'

mydoc

 

設置文件名為一變量,管道輸出到awk,只返回其擴展名。

$ STR="mydoc.txt"

$ echo $STR | awk '{print substr($STR, 7)}'

txt

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM