本文參考的是 ubuntu 下 gawk version 3.1.6 以及 《sed&awk》
一 . awk 簡介
awk 是一種解釋型(tawk除外)文本處理語言
二 . awk 如何運做
命令行參數
shell 會預處理命令行,得到命令行參數(其中包括命令名),以後啓動命令並向它傳遞剩餘的參數。
系統變量ARGV:
一個關聯數組,存放命令行參數,數組下標從0到ARGC-1,ARGV[0]的值爲awk
系統變量ARGC:
命令行參數的個數
ARGV 的元素不包含AWK的選項和腳本
筆者根據 awk 的 info 手冊以及實際操做,臆測出 awk 的大體運做過程以下:
1 . 執行 -v 選項指定的賦值語句
2 . 編譯awk腳本爲某種內部形式(internal form)
3 . 執行 BEGIN 塊
4 . #若是沒有提供輸入文件
if(ARGC == 1)
{
#讀取標準輸入直到輸入結束
while(未讀到到文件末尾)#文件指標準輸入
{
讀取下一個記錄
執行awk腳本
}
}
#遍歷存放命令行參數的數組ARGV
for(i = 1; i < ARGC; i++) #ARGV[0]是awk,不做爲輸入文件
{
if(ARGV[i] 是var=val形式)
{
定義全局變量var的值爲val
}
else #做爲文件名處理
{
if(ARGV[i] 是有效的文件名)
{
while(未讀到文件 ARGV[i] 的末尾)
{
讀取下一個記錄
執行 awk 腳本
}
}
else
{
輸出錯誤,指出文件名ARGV[i]無效
}
}
}
5 . 執行 END 塊
從以上的流程能夠看出:
1 . BEGIN 塊中 能夠得到步驟 1 中賦值語句的變量值
2 . BEGIN 塊中不能夠得到步驟 4 中賦值語句的變量值
讀者能夠觀察如下腳本的運行結果:
$ touch file1 file2 'c=30' #建立三個文件
$ cat file1
1111
2222
$ cat file2
3333
4444
$ cat file3
5555
6666
$ cat 'c=30' #文件名是賦值語句的形式
c=30
c=30
$ cat test1.awk
BEGIN{
print "---------------------"
print "當前在 BEGIN 塊中"
print "a=" a
print "b=" b
print "c=" c
print "共有" , ARGC , "個命令行參數:"
for(i = 0; i < ARGC; i++)
print i , ARGV[i];
}
{
if(FNR == 1)
{
print "---------------------"
print "當前正處理文件" , FILENAME
print "a=" a
print "b=" b
print "c=" c
}
print "第" , FNR , "行", $0
}
END{
print "---------------------"
print "當前在 END 塊中"
}
$ awk -v a=10 -f test1.awk file1 b=20 file2 c=30 file3
---------------------
當前在 BEGIN 塊中 #注意到BEGIN只執行一次,並且是在輸入以前
a=10 #BEGIN塊裏只認識經過 -v 選項賦值的變量a
b= # 不認識
c= # 不認識
共有 6 個命令行參數: #注意到,參數裏面沒有選項(-f)
0 awk #也沒有做爲腳本的文件名test1.awk
1 file1
2 b=20
3 file2
4 c=30
5 file3
---------------------
當前正處理文件 file1
a=10 #-v 選項賦值的變量,全部文件都認識
b= # 讀入file1以後b=20才執行,file1不認識b
c= # c 是誰file1也不知道
第 1 行 1111
第 2 行 2222
---------------------
當前正處理文件 file2
a=10 #-v 選項賦值的變量,全部文件都認識
b=20 #b=20發生以後纔讀入file2,因此認識b
c= #確定不認識
第 1 行 3333
第 2 行 4444
---------------------
當前正處理文件 file3
a=10
b=20
c=30 #原來,儘管當前目錄下有名叫'c=30'的文件,但awk仍然把它當成賦值語句了
第 1 行 5555
第 2 行 6666
---------------------
當前在 END 塊中 #注意到END發生在全部輸入完畢以後
$
三 . 字符串常量
字符串常量是包括在兩個雙引號之間的一系列字符。
awk 可以像 C 語言同樣識別字符串常量中以下轉義字符:
// 字面反斜槓
/a 響鈴(alert)
/b 退格鍵(backspace)
做用:刪除光標左邊的字符並使光標左移一格
/f 進紙鍵(form-feed)
做用:不清楚
/n 新行符(newline character)
/r 回車符(carriage return)
/t 水平製表符(horizontal tab)
/v 垂直製表符(vertical tab)
/xhexdigits 轉義/x以後的 16 進制字符串爲對應的字符
/x1B 表明 ESC 字符
/ddd 將 一位,兩位,三位的十進制數轉化爲對應的字符
/033 或 /33 表明 ESC 字符
/c 字面的 字符 c
注意:
以上轉義序列可以被 awk 的正則表達式識別!!
四 . 正則表達式
gawk 默認支持 POSIX ERE , GAWK 獨有的轉義序列, 以及 gawk 字符串常量支持的 C 類的轉義序列。
POSIX ERE 支持如下形式的正則表達式:
c 匹配單個非元字符c
/c 匹配字面的元字符c
^ 匹配字符串開始
$ 匹配字符串結束
. 匹配任意字符,含換行符
[] 匹配方括號中出現的任意字符
[^] 匹配其中沒有出現的字符
REGEXP1|REGEXP2 匹配REGEXP1 或者 REGEXP2
REGEXP1REGEXP2 匹配REGEXP1 緊接着匹配 REGEXP2
REGEXP+ 匹配REGEXP 的一次及以上出現
REGEXP? 匹配REGEXP 的 0 次或 1 次出現
REGEXP* 匹配REGEXP 的 0 次及以上出現
(REGEXP) 匹配REGEXP , 分組
REGEXP{n} 匹配REGEXP的 n 次出現
REGEXP{n,m} 匹配REGEXP的 n 到 m 次出現
REGEXP{n,} 匹配REGEXP的 最少 n 次出現
REGEXP{,m} 匹配REGEXP的 最多 m 次出現
字符類 [:alnum:]等
等價類 [=e=]等
collating class [.ch.] 等
GAWK 獨有的轉義序列
/y 匹配單詞開頭或者結尾的空串
/B 匹配單詞內部的空串
/` 匹配緩衝區開頭的空串
/' 匹配緩衝區結尾的空串
/w 匹配字母數字下劃線(word-constituent character)
/W 匹配非字母數字下劃線(no word-constituent character)
/< 匹配單詞開頭的空串
/> 匹配單詞結尾的空串
awk 支持的 C 類轉義序列也被 gawk 正則表達式支持:
/n
/r
/t
/v
/a
/b
/xhexdigits
/ddd
五 . 選項
-F fs
指定fs 爲字段分隔符(field separator)
-f script
將script的內容添加到腳本中去。
-f能夠出現屢次,awk會按順序把全部的腳本文件拼接做爲一個完整的腳本
-v var=val
設置變量var 的值爲 val,改變量賦值發生在BEGIN塊以前
若是在賦值語句var=val中出現空格,可使用引號將該語句包圍,以此保護空格
如下選項關乎awk對正則式的理解:
--posix
支持POSIX ERE(包括範圍表達式)
支持 awk 字符串常量支持的轉義字符
不支持上述 GAWK 獨有的轉義序列
--traditional
只支持傳統的UNIX awk 正則表達式,如下均不支持:
1) 範圍表達式
2) 字符類等
3) gawk 獨有的轉義序列(更加不支持了!)
4) awk 字符串常量所支持的那些 C 類轉義序列
--re-interval
強制支持範圍表達式,即便已經指定了 --traditional 選項
若是上訴三種選項均未指定,則 awk 對正則式做以下理解:
支持 POSIX ERE (除了範圍表達式)
支持 GAWK 支持的特殊轉義序列(/y /w等)
支持 AWK 字符串常量支持的特殊轉義字符(/ddd等)
五 . 記錄和字段
1 . 記錄(record)
1) 記錄默認由新行符分隔,新行符是內置系統變量記錄分隔符RS(record separator)的值。
2) RS 一般是一個字符,這個字符用於分隔記錄。
3) RS 若是是多個字符,則被做爲正則表達式,輸入文本中匹配該正則式的部分用於隔開記錄。可是在兼容模式下,只取第一個字符被做爲分隔符。
4) <<sed & awk>> :RS 是 awk 僅僅注意其第一個字符的惟一一個變量。
3) RS 設置爲空串(""),則記錄被空行分隔,此時,不管FS(域分隔符)被設置成什麼值,字段是由新行符隔開的。
4) FNR 記錄當前記錄在當前輸入文件中的編號,即當前記錄是當前文件的第 FNR 個記錄。
5) NR 記錄已經讀入的記錄的個數
2 . 字段(field)
1) 字段分隔符FS(field separator)用於把記錄分隔成多個字段
2) FS一般是單個字符,則字段由該字符分隔。
3) FS是空格時比較特殊,記錄中的字段之間由任意數量空格,任意數量製表符的任意排列分隔。
4) FS含多個字符時被做爲正則表達式
5) NF 記錄當前記錄中的字段數
6) FIELDWIDTH 變量一旦被設置,則 FS 的值會被忽略,即在字段分隔不起做用。
7) awk讀入記錄的同時把字段的值賦給了內置變量,有如下方式可引用字段:
----使用常量引用例如 $10
----使用變量引用例如 $i , $NF
----使用算式返回值例如 $(2+1)
----使用函數返回值引用例如 $int(1+1)
其中,美圓符叫作字段引用操做符
8) 引用負數位置的字段將致使錯誤
9) 引用 $NF 以後的字段將致使 awk 自動生成該字段及以前本沒有的字段並各賦值爲空串,NF被修改,$0 被調整。
六 . 關聯數組
awk 中全部的數組都是關聯數組,表達了一種從字符串到字符串的映射關係。
1 . 關聯數組特色
1) 物理組織無序
2) 模擬多維數組
3) 原理是字符串映射
2 . 下標
關聯數組的下標是括在一對方括號之間的表達式列表,若是有多個表達式,則表達式間用英文逗號分隔。
1) 一維數組
數組是從一個字符串到另外一個字符串的映射,key_str --> val_str ,前者是鍵。
-- arr[ key_str ] 形式,awk 訪問以變量 key_str 的值爲鍵的數組元素
有個例外,當 key_str 是一個數字時,awk 會把它轉換爲字符串,此時arr[key_str]等價於arr["key_str"]
-- arr["key_str"] 形式,awk 訪問以字符串 key_str 爲鍵的數組元素
-- 訪問某個不存在的數組元素時,awk會建立該數組元素,數組元素初始化爲空串
例子:
$ awk 'BEGIN{a[1] = "1111"; print "a[/"1/"]=" , a["1"]; print "a[ 1 ]=" , a[1] }' file
a["1"]= 1111
a[ 1 ]= 1111
$ awk 'BEGIN{a["1"] = "111"; print length(a); print a[var] ; print length(a)}' file
1 # print length(a)輸出 a 的長度,當時有一個元素 a["1"]
# a[var] 至關於 print a[""],而a[""]元素不存在,輸出空串
2 # awk 自動建立了數組元素 a[""]並初始化爲空串 , 因此數組大小變爲 2
$
2) 多維數組
多維數組經過在方括號之間用逗號隔開各維的鍵進行訪問,全部的鍵值都被做爲字符串。
數字鍵會被轉換爲字符串,其中,實數轉換爲字符串可能會丟失信息,實數轉換受 CONFMT 的影響。
多維數組與一維數組遵循一樣的映射原理:
經過把方括號中各字符串用系統變量 SUBSEP 的值銜接起來獲得 key_str ,而後映射到 val_str 。
例子:
i = "30"
j = 20
a["mm",i,j] = "zhong" 至關於 a["30" , "30" , 20] = "zhong"
至關於 a["mm" , "30" , "20"] = "zhong"
意爲把數組元素 a["mm/03430nn"] 賦值爲串 "zhong",其中/034 是SUBSEP 的默認值。
3 . 刪除
經過 delete arr["index"] 刪除單個元素;delete arr 刪除整個數組。
4 . 遍歷
---方法1
while(key in arr) #遍歷 arr 的全部鍵值,若是是多維數組,用(key1,key2,key3)放在 key 的位置。
---方法2
若是可以在構建數組的時候,用連續的或者大小有規律的鍵值,則能夠用for循環遍歷例如:
for(i = 1; i <= NF; i++)
arr[i] = $i;
for(i = 1; i <= NF; i++)
print arr[i];
六 . 操做符(按優先級逐漸下降)
() 分組操做符
$ 字段引用操做符
++ -- 遞增遞減
^ 指數
+ - ! 一元加,一元減,邏輯取反
* / % 乘除取模
+ - 二元加,二元減
space 字符串鏈接符,很牛逼!
| |& 管道I/O,用於print , printf,getline
< > 關係運算符
<= >=
!= ==
~ !~ 匹配,不匹配,字符串匹配的,超牛逼!
in 判斷關聯數組中是否存在以某個鍵爲下標的元素
&& 邏輯與
|| 邏輯或
?: C格式的條件語句,expr?expr1:expr2,若是expr爲真,則該條件語句值爲expr1的值;不然expr2。
= += -= 賦值,^=是將指數運算的結果賦給左參數
*= /= %= ^=
八 . 語句格式
awk 程序的框架是由一個或者多個以下的語句組組成:
condition{ statements }
其中可能出現兩個特殊語句組
BEGIN{ statements } 和 END{ statements }
1 . BEGIN 語句組(若是有),做爲第一個語句組,-v選項賦值語句以後,第一個記錄讀入以前執行。
2 . END 語句組(若是有),做爲最後一個語句組。在全部輸入結束以後執行。
3 . 每次讀入一個記錄,剩下的語句組都要判斷條件是否知足,若是知足就執行。
4 . condition{statements}的condition若是缺失,則對全部記錄都執行方括號中的語句。
5 . statements 若是缺失,則默認執行 print 函數,輸出 $0
6 . 左花括號({) 必須和condition在同一行,condition 和 { 之間能夠隔着空白符。
7 . statements中的每一個statement 能夠用分號隔開
condition 語句能夠是如下形式:
BEGIN
-v選項賦值語句以後,第一個記錄讀入以前執行方括號中的語句。
END
在全部輸入結束以後執行方括號中的語句。
/REGEXP/
當前記錄可以匹配正則表達式REGEXP時,才執行方括號中的語句。
正則式的匹配能力須參考上面的部分。
表達式
《sed&awk》:表達式經過計算返回一個值,表達式由數字,字符串常量,變量,操做符,函數和正則表達式組成。
利用表達式的值做爲判斷根據,若是爲0或者空則不執行
condition && condition 和 condition || condition
表示兩個條件的邏輯與 和 邏輯或
condition ? condition1 : condition2
當condition知足時,若是condition1知足則執行方括號中的語句;
不然,當condition2知足時則執行方括號中的語句。
(condition)
就是把條件用括號包圍起來而已
! condition
當condition不知足時,才執行方括號中的語句。
condition1 , condition2
從第一個知足condition1的記錄開始(包含),到該記錄以後第一個知足condition2的記錄結束(含該記錄)
都執行方括號中的語句。
例子:
# 不是BEGIN的條件下
! BEGIN{ statements }
# 注意左花括號以前能夠有不少空白符
# 注意使用圓括號將表達式括起來不是必須的
0{ statements_impossible_to_execute }
1 - 1{ statements_impossible_to_execute }
(1+1) { statements_doomed_to_excute }
# 注意匹配的是擴展的正則表達式(ERE)
/^/t+/{ statements }
# 注意使用ERE的範圍表達式時須要有 --posix 或者 --re-interval 選項
awk --posix '/a{2,4}/{print}' data
八 . 系統變量
FS 字段分隔符
RS 記錄分隔符
OFS 輸出字段分隔符,默認爲空格;影響print的輸出。
print $0 輸出當前記錄,字段之間由OFS的值隔開;
print "a" , "b" a和 b 之間由 OFS值隔開。
ORS 輸出記錄分隔符,默認爲新行符;影響print的輸出。
每一個 print 語句最後都會輸出 ORS 的值
ARGV 關聯數組,用於存儲傳遞給 awk 的輸入文件名
有 ARGC 個元素,下標所以從0 到 AGRC-1
ARGV[0] 等於 "awk"
ARGV中的文件名若是是等式形式,則被awk做爲賦值語句。
ARGC 數組ARGV中元素的個數,ARGC>= 1; 由於 ARGV[0] 是 "awk"
FNR 當前記錄在當前輸入文件中的位置,即當前文件的第FNR個記錄
FILENAME 當前輸入文件
RSTART 參考match 函數
RLENGTH 參考match 函數
SUBSEP 在多維數組的字符串映射中,用於把各維的鍵值銜接起來造成總體的鍵值
默認值是 "/034"
CONVFMT 數字轉換的格式,默認值"%.6g"
ENVIRON 以環境變量名(大寫)爲鍵值的關聯數組,能夠經過環境變量名訪問數組元素。
OFMT 數字的輸出格式,默認是"%.6g"
還有一些系統變量,不熟悉,不寫了:
ERRNO IGNORECASE LINT PROCINFO TEXTDOMAIN RT
九 . statements
statements 支持 C-style 條件和循環語句,break,continue ;以及其它語句。
------------------------------------------------------------------------------------
if(條件){語句組}[else {語句組}]
while(條件){語句組}
do{語句組}while(條件)
for(語句1;語句2;語句3){語句組}
for(var_key in arr){語句組}
break
continue
delete arr[i]
delete arr
exit [exitcode]
十 . 函數
1 . 算術函數
int ()
返回強制轉換後獲得的整數
cos(expr)
返回餘弦值
sin(expr)
返回正弦值
atan2(y,x)
返回以弧度計算的(y/x)的反正切值
loh(expr)
返回天然對數值
exp(expr)
返回對數值
sqrt(expr)
返回開方後的值
rand()
返回隨機產生的小於1大於等於0的值
srand([expr])
設置rand()函數的種子值爲 expr 的返回值,若是沒有expr 則以當天時間爲種子。
<<sed&awk>>:若是沒有調用srand(),awk在開始執行程序以前默認以某個常量爲參數調用srand(),使得你的程序在每次運行時都從同一個種子數開始。
2 . 字符串函數
length()
返回字符串或者數組的長度
index(str,target)
返回字符串 target 在字符串 str 中第一次出現的位置,若是沒有,返回 0;字符串下標從 1 開始。
match(str , /regexp/ , [, arr])
在字符串 str 中尋找匹配 regexp 的子串,返回第一個匹配子串的位置,若是失配,返回0。
設置系統變量 RSTART 爲匹配子串的起始位置,RLENGTH爲匹配子串的長度;失配則RSTART爲 0 ,RLENGTH 爲 -1。
若是 arr 這個數組,則 arr 被清空,並從下標 "1" 開始保存找到的匹配regexp的子串。
全部匹配的子串被保存在 arr["0"] 中。
split(str , arr [, /separator_regexp/])
把字符串 str 分解到數組 arr 中去,使用匹配正則式 separator_regexp 的子串做爲分隔符。
若是沒有提供 serarator_regexp 則使用 FS 的值做爲分隔符。
返回分解獲得的串的個數,即數組的大小(若是有)
sub(/regexp/ , replacement [,str])
把 str 中第一個匹配正則式 regexp 的子串替換成 replacement 字符串。返回替換的個數。
若是沒有提供 str ,使用 $0 。
replacement 中出現的 & 具備特殊含義,被替換成匹配 regexp 的那部分子串。
要轉義 replacement 中的 & 使用 //&
此外,& 必須被包含在雙引號之間才能被識別,不然出錯。
gsub(/regexp/ , replacement [,str])
把 str 中全部匹配正則式 regexp 的子串替換成 replacement 字符串。返回替換的個數。
其他說明與 sub 同。
tolower(str)
返回字符串 str 中全部大寫字母所有被轉換爲小寫字母以後的串。原串不改變。
toupper(str)
返回字符串 str 中全部小寫字母所有被轉換爲大寫字母以後的串。原串不改變。
substr(str , pos [,len])
返回 str 第 pos 個字符開始的長度爲 len (len >=1) 的串
若是 len 未提供,則返回直到 str 末尾的串
若是 len <= 0 則返回空串
3 . 自定義函數
格式
function func_name(parameter_list){
statements;
return [rt_val]
}
1) 定義函數時,func_name 和左圓括號之間能夠有空格,可是調用函數時不容許。系統自帶函數例外。
2) 自定義函數中定義的變量具備全局性質,將它們定義在圓括號內的形式參數以後,可以使成爲局部變量。
3) 調用自定義函數時,實際參數沒必要包括函數內的局部變量。
4) 應該具備返回值,若是不顯式返回,則默認返回空串。
5) <<sed&awk>>:自定義函數的定義能夠放在腳本中模式操做規則能夠出現的任何地方,一般能夠放在腳本中模式操做規則以前。
4 . print
1) print
輸出 $0 , 後跟 ORS
2) print expr_list
---每一個表達式(expr)之間用逗號和空格的組合進行分隔。
---每一個表達式的結果會被做爲字符串輸出,表達式之間輸出OFS的值
---print 語句的最後輸出 ORS 的值
---單個表達式內的串之間的空格符是做爲字符串銜接符(print "x" "y" 至關於 print "xy")
---能夠重定向到文件
---<<sed&awk>>: 規定 > 出如今任何打印語句的參數列表中時被看做是重定向操做符,若是想要 > 在參數列表中被看做關係運算符,可使用圓括號將表達式或者參數列表括起來。
5 . printf("format_expression" [, arguments])
借用C程序設計語言printf進行格式化輸出,括號能夠省略。
format_expression 由雙引號括起來,其中%以後的字符做爲格式轉換說明符; arguments 由逗號分隔,第 n 個 argument 對應於 format_expression 第 n 個 %轉義說明符; 意爲把該 argument 對應的串轉換爲該格式轉換說明符指明的格式並輸出。
如下爲 % 與格式轉換說明符的組合:
%c 做爲ASCII字符輸出
%d 做爲整數輸出
%i 做爲整數輸出
%e 以浮點格式輸出
%E 以浮點格式輸出
%f 以浮點格式輸出
%g e或f的轉換格式,長度最短,末尾的 0 被去掉
%G E或f的轉換格式,長度最短,末尾的 0 被去掉
%O 做爲無符號八進制數輸出
%s 做爲字符串輸出
%u 做爲無符號的十進制數輸出
%x 做爲無符號的十六進制數輸出,a-f表示 10-15
%X 做爲無符號的十六進制數輸出,A-F表示 10-15
%% 字面的%
上述每個格式轉換說明符(除了%%以外)均可以擴充爲如下形式:
%-width.precision format_specifier
width 指定域寬度,指定域寬的輸出會自動向右對齊,若是想一想左對齊,能夠在百分號以後添加減號(-),見上式。
pricision 指定小數點以後的數字位數
數字的默認轉換格式由系統變量 CONFMT (有的是OFMT) 指定,默認爲 "%.6g"
也能夠是如下形式:
% width.precision format_specifier
%0width.precision format_specifier
%+width.precision format_specifier
%#width.precision format_specifier
關於 printf 函數,不熟悉,只把參考文件貼出來:
- The expression should be left-justified within its field.
space For numeric conversions, prefix positive values with a space,
and negative values with a minus sign.
+ The plus sign, used before the width modifier (see below), says
to always supply a sign for numeric conversions, even if the
data to be formatted is positive. The + overrides the space
modifier.
# Use an 「alternate form」 for certain control letters. For %o,
supply a leading zero. For %x, and %X, supply a leading 0x or
0X for a nonzero result. For %e, %E, %f and %F, the result
always contains a decimal point. For %g, and %G, trailing zeros
are not removed from the result.
0 A leading 0 (zero) acts as a flag, that indicates output should
be padded with zeroes instead of spaces. This applies even to
non-numeric output formats. This flag only has an effect when
the field width is wider than the value to be printed.
width The field should be padded to this width. The field is normally
padded with spaces. If the 0 flag has been used, it is padded
with zeroes.
.prec A number that specifies the precision to use when printing. For
the %e, %E, %f and %F, formats, this specifies the number of
digits you want printed to the right of the decimal point. For
the %g, and %G formats, it specifies the maximum number of sig‐
nificant digits. For the %d, %o, %i, %u, %x, and %X formats, it
specifies the minimum number of digits to print. For %s, it
specifies the maximum number of characters from the string that
should be printed.
6 . getline
1) getline
讀取下一個記錄,覆蓋$0,設置FNR NR NF
2) getline "-"
從標準輸入讀取一行
3) getline <"filename"
讀入文件filename的下一個記錄,只更新NF
4) getline var
讀取下一個記錄,存入變量var ,設置 FNR NR。 $0 不變,NF 不變
5) getline var <"file_name"
讀入文件file的下一個記錄,存入變量var 。 FNR NR NF $0均不變。
注:
1) 不能寫成 getline() , 它的語法不容許有圓括號。
2) 返回值不是字符串
3) 成功讀取返回 1 ;讀到文件末尾返回 0 ;遇到錯誤返回 -1
4) 從流中/文件/管道中讀取時,能夠直接以字符串常量指定文件名,也能夠經過變量提供。
7 . close
用於關閉已經打開的文件或管道,以此能夠
1)限制打開的文件和管道的數量
2)關閉一個管道能夠運行同一個命令兩次
3)關閉一個管道使得其輸出的成果能夠被訪問
例子2):
$ cat test.awk
{
"date" | getline var
print var
close("date") #關閉管道
"date" | getline var2
print var2
}
$ awk -f test.awk file
Fri Mar 4 21:35:09 CST 2011
Fri Mar 4 21:35:09 CST 2011
$ cat test.awk
{
"date" | getline var
print var
# close("date") #不關閉管道
"date" | getline var2
print var2
}
$ awk -f test.awk file #產生空行
Fri Mar 4 21:35:09 CST 2011
$
例子3):
$ cat test.awk
{
print $0 | "sort > outcome"
}
END{
close("sort > outcome") #關閉管道
while(getline var<"outcome"){
print var
}
}
$ cat data
aa
bb
ff
cc
$ awk -f test.awk data
$ cat outcome
aa
bb
cc
ff
$
8 . next
讀入下一個記錄,修改$0,NF ,NR , FNR
若是已經讀到文件末尾,那麼執行END塊(若是有)
不然從第一個 condition{statements}從新開始執行
例子:
$ cat test.awk
{
print "next 前"
print "$0 =" $0
print "FNR=" FNR
print "NF =" NF
print "NR =" NR
next
print "next 後"
print "$0 =" $0
print "FNR=" FNR
print "NF =" NF
print "NR =" NR
}
END{
print "在 END 中"
}
$ cat data
aa bb
aa bb cc dd
$ awk -f test.awk data
next 前
$0 =aa bb #file的第一行
FNR=1
NF =2
NR =1
next 前 #注意,不是 "next 後"
$0 =aa bb cc dd #file的第二行
FNR=2
NF =4
NR =2
在 END 中
$
9 . nextfile
讀入下一個文件的第一個記錄,修改$0 , NF , NR , FNR
若是發現全部文件的輸入數據都已經讀完,執行END塊(若是有)
不然從第一個 condition{statements}從新開始執行
10 . exit
exit 使得主輸入循環退出並將控制轉移到 END 規則,若是END存在的話。
11 . system("command_line")
執行 command_line , 返回命令的退出狀態(exit status)
補充內容:
1 . 關於註釋
與 sed 不一樣,awk 容許在程序的任何地方添加註釋
2 . 關於斷行的技巧
一種處理斷行的方法就是使用 length 得到每一個字段的長度,這樣,當累計的長度超過某個特定的數據時,就能夠指定一個換行。
3 . 看不懂的
注意, awk 和sed 不同,不能「記住」前面的正則式,即不能用語法// 來引用最後的正則表達式。
第八章,有兩個語句能影響輸入循環,next 和 exit 。一些 awk 不容許在用戶自定義的函數中使用 next 語句。exit 使得主輸入循環退出並將控制轉移到 END 規則,若是 END 存在的話。若是沒有定義END 規則或者在end 中使用exit 則終止腳本的執行。git
轉自:http://blog.csdn.net/yaozhiyi/article/details/6224847正則表達式