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 '/./'