1. 程式人生 > >AWK-詳解著名的awk Oneliner,第三部分:選擇性輸出特定行

AWK-詳解著名的awk Oneliner,第三部分:選擇性輸出特定行

awk ' NR < 11 ' 

如前所述,這裡省略了動作,即為列印輸出。匹配模式是變數NR需要小於11,NR即為當前的行號。這個寫法很簡單,但是有一個問題,在NR大於10的時候,awk其實還是對每行進行了判斷,如果檔案很大,比如說有上萬行,浪費的時間是無法忽略的。所以,更好的寫法是

awk '1; NR = 10 { exit }' 

第一句對當前行進行輸出。第二句判斷是不是已經到了第10行,如果是則退出。

輸出檔案的第一行(模擬 head -n 1 )

awk 'NR > 1 { exit }; 1' 

這個例子與前一個很相似,中心思想就是第二行就退出。

輸出檔案的最後兩行(模擬 tail -n 2 )

awk '{ y=x "\n" $0; x=$0}; END { print y }' 

的確,這一句看起來確實有些彆扭。第一句總是把一個在當前行前面再加上變數x的內容賦值給y,然後用x記錄當前行內容。這樣的效果是y的內容始終是上一行加上當前行的內容。在最後,輸出y的內容。如果仔細看的話,不難發現這個寫法是很不高效的,因為它不停的進行賦值和字串連線,只為了找到最後一行!所以,如果你想要輸出檔案的最後兩行,tail -n 2是最好的選擇。

輸出檔案的最後一行(模擬 tail -n 1 )

awk 'END { print }' 

句法方面沒什麼好說的,print省略引數即是等價於print $0。但是這個語句可能不能被非GNU awk的某些awk版本正常執行,如果為了相容,下面的寫法是最安全的:

awk '{ rec = $0 }; END { print rec }' 

輸出只匹配某些模式的行(模擬 grep )

awk '/regex/' 

似乎沒什麼好說的了。

輸出不匹配某些模式的行(模擬 grep -v )

awk '!/regex/' 

匹配模式前加“!”就是否定判斷結果。

輸出匹配模式的行的上一行,而非當前行

awk '/regex/ { print x }; { x = $0 }' 

變數x總是用來記錄上一行的內容,如果模式匹配了當前行,則輸出x的內容。

輸出匹配模式的下一行

awk '/regex/ { getline; print }' 

這裡使用了getline函式取得下一行的內容並輸出。getline的作用是將$0的內容置為下一行的內容,並同時更新NR,NF,FNR變數。如果匹配的是最後一行,getline會出錯,$0不會被更新,最後一行會被列印。

輸出匹配AA或者BB或者CC的行

awk '/AA|BB|CC/' 

沒什麼好說的,正則表示式。如果有看不懂的朋友,請自行學習正則表示式。

輸出長過65個字元的行

awk 'length > 64' 

length([str])返回字串的長度,如果引數省略,即是以$0作為引數,括號也可以省略了。

輸出短於65個字元的行

awk 'length < 65' 

和上例基本一樣。

輸出從匹配行到最後一樣的內容

awk '/regex/,0' 

這裡使用了“pattern1,pattern2”的形式來指定一個匹配的範圍,其中pattern2這裡為0,也就是false,所以一直會匹配到檔案結束。

從第8行輸出到第12行

awk 'NR==8,NR==12' 

同上例,這也是個範圍匹配。

輸出第52行

awk 'NR==52' 

如果想要少執行些不必要的迴圈,就這樣寫:

awk 'NR==52 {print;exit}' 

輸出兩次正則表示式匹配之間的行

awk '/regex1/, /regex2/' 

刪除所有的空行

awk NF 

NF為真即是非空行。另外一種寫法是用正則表示式:

awk '/./'