在文件中查找與模式匹配的行,而後在它們上面執行特定的操做。正則表達式
awk [ -F Ere ] [ -v Assignment ] ... { -f ProgramFile | 'Program' } [ [ File ... | Assignment ... ] ] ...編程
awk 命令利用一組用戶提供的指令來將一組文件和用戶提供的擴展正則表達式比較,一次一行。而後在任何與擴展正則表達式匹配的行上執行操做。awk 處理的最大記錄大小爲 10KB。數組
awk 命令的模式搜索比 grep 命令的搜索更經常使用,且它容許用戶在輸入文本行上執行多個操做。awk 命令編程語言不須要編譯,並容許用戶使用變量、數字函數、字符串函數和邏輯運算符。編程語言
awk 命令受到 LANG、LC_ALL、LC_COLLATE、LC_CTYPE、LC_MESSAGES、LC_NUMERIC、NLSPATH 和 PATH 環境變量的影響。函數
本章中包括如下主題:編碼
awk 命令採起兩種類型的輸入:輸入文本文件和程序指令。spa
搜索和操做在輸入文本文件上執行。文件以下指定:命令行
若是用 File 變量指定多個文件,則文件以指定的順序處理。3d
用戶提供的指令控制 awk 命令的操做。這些指令來自命令行的‘Program’變量或來自用 -f 標誌和 ProgramFile 變量一塊兒指定的文件。若是指定多個程序文件,這些文件以指定的順序串聯,且使用指令的生成的順序。code
awk 命令從輸入文本文件中的數據產生三種類型的輸出:
能夠在同一個文件上執行全部三種類型的輸出。awk 命令識別的編程語言容許用戶重定向輸出。
文件如下列方式處理:
awk 編程語言中的 BEGIN 語句容許用戶指定在讀取第一個記錄前要執行的一組指令。這對於初始化特殊變量特別有用。
記錄是由記錄分隔符隔開的一組數據。記錄分隔符的缺省值是換行字符,它使文件中的每一行成爲一個單獨的記錄。記錄分隔符能夠經過設置 RS 特殊變量來更改。
命令指令能夠指定應比較記錄內的特定字段。缺省狀況下,字段由空白區(空格或跳格)隔開。每一個字段由一個字段變量表示。記錄中的第一個字段指定爲 $1 變量,第二個字段指定爲 $2 變量,以此類推。整個記錄指定爲 $0 變量。字段分隔符能夠經過在命令行使用 -F 標誌或經過設置 FS 特殊變量來更改。FS 特殊變量能夠設置爲下列值:空格、單個字符或擴展正則表達式。
awk 編程語言中的 END 語句容許用戶指定在讀取最後一個記錄後要執行的操做。這對於發送有關 awk 命令完成了什麼工做的消息特別有用。
awk 命令編程語言由如下格式的語句構成:
Pattern { Action }
若是一個記錄與指定模式相匹配,或包含與該模式匹配的字段,則執行相關的操做。能夠指定沒有操做的模式,這種狀況下,包含該模式的整行寫至標準輸出。爲每一個輸入記錄執行指定的沒有模式的操做。
在 awk 命令語言語法中使用四種類型的模式:
awk 命令使用的擴展正則表達式相似於 grep 或 egrep 命令使用的表達式。擴展正則表達式的最簡單的形式就是包括在斜槓中的一串字符。例如,假定一個名爲 testfile 的文件具備如下內容:
smawley, andy smiley, allen smith, alan smithern, harry smithhern, anne smitters, alexis
輸入如下一行命令:
awk '/smi/' testfile
將把包含 smi 字符串的具體值的全部記錄打印至標準輸出。在這個示例中,awk 命令的程序 '/smi/' 是一個沒有操做的模式。輸出是:
smiley, allen smith, alan smithern, harry smithhern, anne smitters, alexis
如下特殊字符用於造成擴展正則表達式:
awk 命令識別大多數用於 C 語言約定中的轉義序列,以及 awk 命令自己用做特殊字符的幾個轉義序列。轉義序列是:
轉義序列 | 表示的字符 |
---|---|
\" | \"(雙引號)標記 |
\/ | /(斜槓)字符 |
\ddd | 其編碼由 一、2 或 3 位八進制整數表示的字符,其中 d 表示一個八進制數位 |
\\ | \ ( 反斜槓 ) 字符 |
\a | 警告字符 |
\b | 退格字符 |
\f | 換頁字符 |
\n | 換行字符(請參閱如下的注) |
\r | 回車字符 |
\t | 跳格字符 |
\v | 垂直跳格 |
注:除了在 gsub、 match、 split 和 sub 內置函數中,擴展正則表達式的匹配都基於輸入記錄。記錄分隔符字符(缺省狀況下爲換行字符)不能嵌套在表達式中,且沒與記錄分隔符字符匹配的表達式。若是記錄分隔符不是換行字符,則可與換行字符匹配。在指定的四個內置函數中,匹配基於文本字符串,且任何字符(包含記錄分隔符)能夠嵌套在模式中,這樣模式與適當的字符相匹配。然而,用 awk 命令進行的全部正則表達式匹配中,在模式使用一個或多個 NULL(空)字符將生成未定義的結果。
關係運算符 <(小於)、>(大於)、<=(小於或等於)、>=(大於或等於)、= =(等於)和 !=(不等於)可用來造成模式。例如,模式:
$1 < $4
將與第一個字段小於第四個字段的記錄匹配。關係運算符還和字符串值一塊兒使用。例如:
$1 =! "q"
將與第一個字段不是 q 的全部記錄匹配。字符串值還能夠根據校對值匹配。例如:
$1 >= "d"
將與第一個字段以字符 a、b、c 或 d 開頭的全部記錄匹配。若是未給出其它信息,則字段變量做爲字符串值比較。
可使用三種選項組合模式:
/begin/,/end/
與包含字符串 begin 的記錄以及該記錄和包含字符串 end 之間的全部記錄(包含包括字符串 end 的記錄)匹配。
$1 == "al" && $2 == "123"
與第一個字段是 al 且第二個字段是 123 的記錄匹配。
用 BEGIN 模式指定的操做在讀取任何輸入以前執行。用 END 模式指定的操做在讀取了全部輸入後執行。容許多個 BEGIN 和 END 模式,並以指定的順序處理它們。在程序語句中 END 模式能夠在 BEGIN 模式以前。若是程序僅由 BEGIN 語句構成,則執行操做且不讀取輸入。若是程序僅由 END 語句構成,則在任何操做執行前讀取全部輸入。
有多種類型的操做語句:
操做語句括在 { } (花括號) 中。若是語句指定爲沒有模式,則它們在每一個記錄上執行。在括號裏能夠指定多個操做,但操做間必須以換行字符或 ;(分號)分隔,且語句以它們出現的順序處理。操做語句包含:
算術語句 |
算術運算符 +(加號), - (減號), / (除號), ^ (冪), * (乘號), % (係數)用於格式: 表達式 運算符 表達式 這樣,語句: $2 = $1 ^ 3 將第一個升爲三次方的字段的值指定給第二個字段。 |
一元語句 |
一元 -(減號)和一元 +(加號)如在 C 編程語言中操做: +Expression 或 -Expression |
增量和減量語句 |
增量前語句和減量前語句如在 C 編程語言中操做: ++Variable 或 --Variable 增量後語句和減量後語句如在 C 編程語言中操做: Variable++ 或 Variable-- |
字符串串聯語句 |
字符串值能夠經過緊挨着陳述來串聯。例如: $3 = $1 $2 將字段變量 $1 和 $2 中的字符串的串聯指定給字段變量 $3。 |
awk 命令語言使用算術函數、字符串函數和通常函數。若是打算編寫一個文件,且稍後在同一個程序裏讀取它,則 close 子例程語句是必需的。
如下算術函數執行與 C 語言中名稱相同的子例程相同的操做:
字符串函數是:
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 參數指定的表達式並返回最後生成的字符串。 |
通常函數是:
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 特殊變量。 |
注:全部 getline 函數的格式對於成功輸入返回 1,對於文件結束返回零,對於錯誤返回 -1。
用戶定義的函數如下列格式說明:
function Name (Parameter, Parameter,...) { Statements }
函數能夠指向 awk 命令程序中的任何位置,且它的使用能夠優先於它的定義。此函數的做用域是全局的。
函數參數能夠是標量或數組。參數名稱對函數而言是本地的;全部其它變量名稱都是全局的。同一個名稱不該用做不一樣的實體;例如,一個參數名稱不能用做函數名稱又用做特殊變量。具備全局做用域的變量不該共享一個函數的名稱。同個做用域中的標量和數組不該具備同一個名稱。
函數定義中的參數數量沒必要和調用函數時使用的參數數量匹配。多餘的形式參數可用做本地變量。額外的標量參數初始化後具備等同於空字符串和數字值爲 0(零)的字符串值;額外的數組參數初始化爲空數組。
當調用函數時,函數名稱和左括號之間沒有空格。函數調用能夠是嵌套的或循環的。從任何嵌套的或循環函數函數調用返回時,全部調用函數的參數的值應保持不變,除了引用傳送的數組參數。return 語句可用於返回一個值。
在函數定義內,在左 { ( 花括號 ) 以前和右 } ( 花括號 ) 以後的換行字符是可選的。
函數定義的一個示例是:
function average ( g,n) { for (i in g) sum=sum+g[i] avg=sum/n return avg }
數組 g 和變量 n 以及數組中的元素個數傳遞給函數 average。而後函數得到一個平均值並返回它。
awk 命令編程語言中的大部分條件語句和 C 編程語言中的條件語句具備相同的語法和功能。全部條件語句容許使用{ } (花括號) 將語句組合在一塊兒。能夠在條件語句的表達式部分和語句部分之間使用可選的換行字符,且換行字符或 ;(分號)用於隔離 { } (花括號) 中的多個語句。C 語言中的六種條件語句是:
awk 命令編程語言中的五種不遵循 C 語言規則的條件語句是:
awk 命令編程語言的兩種輸出語句是:
須要如下語法: print [ ExpressionList ] [ Redirection ] [ Expression ] print 語句將 ExpressionList 參數指定的每一個表達式的值寫至標準輸出。每一個表達式由 OFS 特殊變量的當前值隔開,且每一個記錄由 ORS 特殊變量的當前值終止。 可使用 Redirection 參數重定向輸出,此參數可指定用 >(大於號)、>>(雙大於號)和 |(管道)進行的三種輸出重定向。Redirection 參數指定如何重定向輸出,而 Expression 參數是文件的路徑名稱(當 Redirection 參數是 > 或 >> 時)或命令的名稱(當 Redirection 參數是 | 時)。 |
|
printf | 須要如下語法: printf Format [ , ExpressionList ] [ Redirection ] [ Expression ] printf 語句將 ExpressionList 參數指定的表達式以 Format 參數指定的格式寫至標準輸出。除了 c 轉換規範(%c)不一樣外,printf 語句和 printf 命令起徹底相同的做用。Redirection 和 Expression 參數與在 print 語句中起相同的做用。 對於 c 轉換規範:若是自變量具備一個數字值,則編碼是該值的字符將輸出。若是值是零或不是字符集中的任何字符的編碼,則行爲未定義。若是自變量不具備數字值,則輸出字符串值的第一個字符;若是字符串不包含任何字符,則行爲未定義。 |
注:若是 Expression 參數爲 Redirection 參數指定一個路徑名稱,則 Expression 參數將括在雙引號中以確保將它看成字符串對待。
變量能夠是標量、字段變量、數組或特殊變量。變量名稱不能以數字開始。
變量可僅用於引用。除了函數參數之外,它們沒有明確說明。未初始化的標量變量和數組元素具備一個爲 0(零)的數字值和一個爲空字符串(" ")的字符串值。
根據上下文,變量呈現出數字或字符串值。每一個變量能夠具備數字值和/或字符串值。例如:
x = "4" + "8"
將值 12 指定給變量 x。對於字符串常量,表達式應括在 " "(雙引號)標記中。
數字和字符串間沒有顯式轉換。要促使將表達式看成一個數字,向它添加 0(零)。要促使將表達式看成一個字符串,則添加一個空字符串(" ")。
字段變量由 $(美圓符號)後跟一個數字或數字表達式來表示。記錄中的第一個字段指定爲 $1 變量,第二個字段指定爲 $2,以次類推。$0 字段變量指定給整個記錄。新字段能夠經過指定一個值給它們來建立。將一個值指定給不存在的字段(即任何大於 $NF 字段變量的當前值的字段)將促使建立任何干擾字段(指定爲空字符串),增長 NF 特殊變量的值,並促使從新計算 $0 記錄變量。新字段由當前字段分隔符(FS 特殊變量的值)隔開。空格和跳格是缺省字段分隔符。要更改字段分隔符,請使用 -F 標誌或 在 awk 命令程序中爲 FS 特殊變量指定另外一個值。
數組初始爲空且它們大小可動態更改。數組由一個變量和在 [ ](方括號)中的下標來表示。下標或元素標識符能夠是幾個字符串,它們提供了一種相關數組能力。例如,程序:
/red/ { x["red"]++ } /green/ { y["green"]++ }
增長 red 計數器和 green 計數器的計數。
數組能夠用一個以上的下標來創建索引,相似於一些編程語言中的多維數組。由於 awk 命令的編程數組其實是一維的,經過串聯各獨立表達式的字符串值(每一個表達式由 SUBSEP 環境變量的值隔開)來將以逗號隔開的下標轉換爲單個字符串。因此,如下兩個索引操做是等同的:
x[expr1, expr2,...exprn]
和
x[expr1SUBSEPexpr2SUBSEP...SUBSEPexprn]
當使用 in 運算符時,一個多維 Index 值應包含在圓括號之中。除了 in 運算符,任何對不存在數組元素的引用將自動建立該元素。
如下變量對於 awk 命令具備特殊含義:
ARGC | ARGV 數組中的元素個數。此值能夠更改。 |
ARGV | 其每一個成員包含 File 變量之一或 Assignment 變量之一的數組按序從命令行取出,並從 0(零)編號至 ARGC -1。當每一個輸入文件完成時,ARGV 數組的下一個成員提供下一個輸入文件的名稱,除非: |
CONVFMT | 將數字轉換爲字符串的 printf 格式(除了使用 OFMT 特殊變量的輸出語句)。缺省值爲「%.6g」。 |
ENVIRON | 表示運行 awk 命令的環境的數組。該數組的每一個元素在如下格式中: ENVIRON [ "Environment VariableName" ] = EnvironmentVariableValue 當 awk 命令開始執行時設置這些值,且到執行結束前一直使用該環境,不考慮 ENVIRON 特殊變量的任何修改。 |
FILENAME | 當前輸入文件的路徑名稱。在執行 BEGIN 操做的過程當中,FILENAME 的值未定義。在執行 END 操做的過程當中,該值是處理的最後一個輸入文件的名稱。 |
FNR | 當前文件中的當前輸入記錄的個數。 |
FS | 輸入字段分隔符。缺省值是空格。若是輸入字段分隔符是空格,則任何數目的語言環境定義的空格能夠分隔字段。FS 特殊變量能夠有兩種附加的值:
|
NF | 當前記錄中的字段個數,最大數 99 個。在 BEGIN 操做中,除非先前發出不帶 Variable 參數的 getline 函數,不然 NF 特殊變量未定義。在 END 操做中,除非在輸入 END 操做以前發出不帶 Variable 參數的後續的、重定向的 getline 函數,不然 NF 特殊變量保留它爲讀取的最後一個記錄而具備的值。 |
NR | 當前輸入記錄的個數。在 BEGIN 操做中,NR 特殊變量的值是 0(零)。在 END 操做中,值是最後處理的記錄的編號。 |
OFMT | 在輸出語句中將數字轉換爲字符串的 printf 格式。缺省值爲「%.6g」。 |
OFS | 輸出字段分隔符(缺省值是空格)。 |
ORS | 輸出記錄分隔符(缺省值是換行字符)。 |
RLENGTH | 由 match 函數來匹配的字符串的長度。 |
RS | 輸入記錄分隔符(缺省值是換行字符)。若是 RS 特殊變量爲空,則記錄以一個或多個空行的序列隔開;第一個空行或最後一個空行在輸入的開始和結束都不會產生空記錄;換行字符始終是一個字段分隔符,不考慮 FS 特殊變量的值。 |
RSTART | 由 match 函數來匹配的字符串的起始位置,從 1 開始編號。等同於 match 函數的返回值。 |
SUBSEP | 隔開多個下標。缺省值是 \031。 |
該命令返回如下出口值:
成功完成。 | |
>0 | 發生錯誤。 |
能夠經過使用 exit [ Expression ] 條件語句來更改程序中的退出狀態。
awk 'length >72' chapter1
這選擇 chapter1 文件中長於 72 個字符的每一行,並將這些行寫至標準輸出,由於未指定 Action。製表符以 1 個字符計數。
awk '/start/,/stop/' chapter1
awk -f sum2.awk chapter1
如下程序 sum2.awk,計算了輸入文件 chapter1 中的第二列的數字的總和與平均值:
{ sum += $2 } END { print "Sum: ", sum; print "Average:", sum/NR; }
第一個操做將每行的第二個字段的值添加至變量 sum。當第一次被引用時,全部的變量都初始化爲數字值 0(零)。第二個操做前的模式 END 使那些操做在讀取了全部輸入文件以後才執行。用於計算平均值的 NR 特殊變量是一個指定已經讀取的記錄的個數的特殊變量。
awk '{ print $2, $1 }' chapter1
awk -f sum3.awk chapter2打印文件 chapter2 的前兩個字段(用逗號和/或空格和製表符隔開),而後合計第一列,並打印總和與平均值:
BEGIN {FS = ",|[ \t]+"} {print $1, $2} {s += $1} END {print "sum is",s,"average is", s/NR }