除了可以從標準輸入或非選項型引數所指定的檔案中讀取資料,還可以使用getline從其它各種渠道獲取需要處理的資料,它的用法有很多種。
getline的返回值:
為了健壯性,getline時強烈建議進行判斷。例如:
上面的getline的括號盡量加上,因為getline < 0
表示的是輸入重定向,而不是和數值0進行小於號的比較。
getline無引數時,表示從當前正在處理的檔案中立即讀取下一條記錄儲存到$0中,並進行字段分割,然後繼續執行後續**邏輯。此時的getline會設定nf、rt、nr、fnr、$0和$n。
next也可以讀取下一行。
它們之間的區別用偽**描述,類似於:
# next例如,匹配到某行之後,再讀一行就退出:exec
9<>filename
while read -u 9 line;do
...code...
continue # next
...code... # 這部分**在本輪迴圈當中不再執行
done
# getline
while read -u 9 line;do
...code...
read -u 9
line # getline
...code...
done
[root@docker-01 ~]# awk為了更健壯,應當對getline的返回值進行判斷。'/^1/
'a.txt
1 bob male 28 [email protected] 18023394012
2 alice female 24 [email protected] 18084925203
[root@docker-01 ~]# awk沒有引數的getline是讀取下一條記錄之後將記錄儲存到'/^1/;print}
'a.txt
1 bob male 28 [email protected] 18023394012
2 alice female 24 [email protected] 18084925203
10 bruce female 27 [email protected] 13942943905
[root@docker-01 ~]# awk
'/^1/;print}
'a.txt
1 bob male 28 [email protected] 18023394012
$0
中,並對該記錄進行欄位的分割。
乙個引數的getline是將讀取的記錄儲存到指定的變數當中,並且不會對其進行分割。
getline var此時的getline只會設定rt、nr、fnr變數和指定的變數var。因此$0和$n以及nf保持不變。
filename需使用雙引號包圍表示檔名字串,否則會當作變數解析getline < "c.txt"
。此外,如果路徑是使用變數構建的,則應該使用括號包圍路徑部分。例如getline < dir "/" filename
中使用了兩個變數構建路徑,這會產生歧義,應當寫成getline 。
注意,每次從filename讀取之後都會做好位置偏移標記,下次再從該檔案讀取時將根據這個位置標記繼續向後讀取。
例如,每次行首以1開頭時就讀取c.txt檔案的所有行。
awk '
/^1/;
close("c.txt")
}' a.txt
上面的close("c.txt")
表示在while(getline)
讀取完檔案之後關掉,以便後面再次讀取,如果不關掉,則檔案偏移指標將一直在檔案結尾處,使得下次讀取時直接遇到eof。
cmd | getline var
:從shell命令cmd的輸出結果中讀取資料儲存到var中
如果要再次執行cmd並讀取其輸出資料,則需要close關閉該命令。例如close("seq 1 5")
,參見下面的示例。
例如:每次遇到以1開頭的行都輸出seq命令產生的1 2 3 4 5
。
awk '/^1/;close("seq 1 5")}' a.txt
再例如,呼叫shell的date命令生成時間,然後儲存到awk變數cur_date中:
awk '
/^1/' a.txt
可以將cmd儲存成乙個字串變數。
awk '
begin
/^1/' a.txt
更為複雜一點的,cmd中可以包含shell的其它特殊字元,例如管道、重定向符號等:
awk '
/^1/y 2>/dev/null"|getline) > 0)
close("seq 1 5 | xargs -i echo x{}y 2>/dev/null")
}' a.txt
awk雖然強大,但是有些資料仍然不方便處理,這時可將資料交給shell命令去幫助處理,然後再從shell命令的執行結果中取回處理後的資料繼續awk處理。
awk通過|&
符號來支援coproc。
awk_print[f] "something" |& shell_cmd
shell_cmd |& getline [var]
這表示awk通過print輸出的資料將傳遞給shell的命令shell_cmd去執行,然後awk再從shell_cmd的執行結果中取回shell_cmd產生的資料。
例如,不想使用awk的substr()來取子串,而是使用sed命令來替換。
awk '
begin
nr>1' a.txt
對於awk_print |& cmd; cmd |& getline
的使用,須注意的是:
對於那些要求讀完所有資料再執行的命令,例如sort命令,它們有可能需要等待資料已經完成後(遇到eof標記)才開始執行任務,對於這些命令,可以多次向coprocess中寫入資料,最後close(cmd,"to")
讓coprocess執行起來。
例如,對age欄位(即$4
)使用sort命令按數值大小進行排序:
awk '
begin
# 將所有行都寫進管道
nr>1
endclose(cmd);
} ' a.txt
close(filename)
close(cmd,[from | to]) # to引數只用於coprocess的第乙個階段
如果close()關閉的物件不存在,awk不會報錯,僅僅只是讓其返回乙個負數返回值。
close()有兩個基本作用:
awk中任何檔案都只會在第一次使用時開啟,之後都不會再重新開啟。只有關閉之後,再使用才會重新開啟。
例如乙個需求是只要在a.txt中匹配到1開頭的行就輸出另乙個檔案x.log的所有內容,那麼在第一次輸出x.log檔案內容之後,檔案偏移指標將在x.log檔案的結尾處,如果不關閉該檔案,則後續所有讀取x.log的檔案操作都從結尾處繼續讀取,但是顯然總是得到eof異常,所以getline返回值為0,而且也讀取不到任何資料。所以,必須關閉它才能在下次匹配成功時再次從頭讀取該檔案。
awk '
/^1/
close("x.log")
}' a.txt
在處理coprocess的時候,close()可以指定第二個引數"from"或"to",它們都針對於coproc而言,from時表示關閉coproc |& getline
的管道,使用to時,表示關閉print something |& coproc
的管道。
awk '
begin
nr>1' a.txt
上面的第乙個close是必須的,否則sed會一直阻塞。因為sed一直認為還有資料可讀,只有關閉管道傳送乙個eof,sed才會開始處理。 TCP IP詳解筆記 9
tftp簡單文字傳輸協議和bootp引導程式協議 tftp協議 同時為了允許多個客戶併發的進行系統引導,tftp通過為每個客戶分配乙個埠號來實現併發。tftp協議沒有提供安全性。bootp引導程式協議 在arp協議時說過可以通過rarp來得到自己的ip,但這只能得到ip位址,且該子網下必須存在rar...
const用法詳解
物件導向是c 的重要特性.但是c 在c的基礎上新增加的幾點優化也是很耀眼的 就const直接可以取代c中的 define 以下幾點很重要,學不好後果也也很嚴重 1.const常量,如const int max 100 優點 const常量有資料型別,而巨集常量沒有資料型別。編譯器可以對前者進行型別安...
const 用法詳解
物件導向是c 的重要特性.但是c 在c的基礎上新增加的幾點優化也是很耀眼的 就const直接可以取代c中的 define 以下幾點很重要,學不好後果也也很嚴重 1.const常量,如const int max 100 優點 const常量有資料型別,而巨集常量沒有資料型別。編譯器可以對前者進行型別安...