知識點
先說一下重要的知識點:
getline;
在awk
中可以用於控制“迴圈”。getline;
之後,awk會改變對應的NF,NR,FNR和$0等內部變數getline;
拿到的是下一行而不是當前行,概念想象為++i
操作即可。
介紹
getline命令改變了awk的執行邏輯,是awk命令不可或缺的一部分。awk本質上就是一個for迴圈,它每次對輸入檔案的一行進行處理,然後轉而執行下一行,直到整個檔案的每一行都被執行完畢。整個過程是自動的無需做什麼。
getline
命令卻可以讓你去控制迴圈。當然,getline命令執行後,awk會設定NF,NR,FNR和$0等這些內部變數。
簡單使用
我們先看一個簡單的例子,列印出從1到10之間的偶數:
[zxd@localhost kafka2.8.X]$ seq 10 | awk '{getline; print $0}'
2
4
6
8
10
這個命令的的執行邏輯是執行一個for迴圈從1到10,在迴圈內部先執行getline;
然後列印$0
,$0
指向的就是當前的變數,注意getline;
獲取的是獲取當前行的下一行,類似我們程式語言的++i
,注意getline;
之後,awk會改變對應的NF,NR,FNR和$0等內部變數,所以$0
值會隨著遍歷改變,最後實現列印偶數效果。
根據上面的介紹我們可以推匯出列印奇數的邏輯:
[zxd@localhost kafka2.8.X]$ seq 10 | awk '{ print $0;getline;}'
1
3
5
7
9
臨時變數使用
奇偶行對調列印,原來在奇數行的內容將其列印在偶數行,原來在偶數行的內容將其列印在奇數行,要實現這個功能,需要在迴圈中使用臨時變數:
seq 10 | awk '{getline tmp; print tmp; print $0}'
結果如下:
[zxd@localhost kafka2.8.X]$ seq 10 | awk '{getline tmp; print tmp; print $0}'
2
1
4
3
6
5
8
7
10
9
檔案合併
在上面的例子當中tmp
變數是不會改變的。
getline也可以從另外一個檔案中讀取內容。下面例子實現將兩個檔案的每一行都列印在一行上:
vim b.txt
1
2
3
4
5
vim c.txt
5
6
7
8
9
10
[zxd@localhost ~]$ awk '{printf "%s ", $0; getline < "c.txt"; print $0}' b.txt
1 6
2 7
3 8
4 9
5 10
日期獲取
getline也可以用來執行一個UNIX命令,並得到它的輸出。下面例子透過getline得到系統的當前時間:
awk 'BEGIN {"date" | getline; close("date"); print $0}'
[zxd@localhost ~]$ awk 'BEGIN {"date" | getline; close("date"); print $0}'
Wed Mar 1 00:34:01 CST 2023