awk內建變數NR與FNR使用詳解

pythontab發表於2018-08-29

awk內建變數NR與FNR

awk 命令中NR表示從awk開始執行後,按照記錄分隔符讀取的資料次數,預設的記錄分隔符為換行符,因此預設的就是讀取的資料行數,NR可以理解為Number of Record的縮寫。

在awk處理多個輸入檔案的時候,在處理完第一個檔案後,NR並不會從1開始,而是繼續累加,因此就出現了FNR,每當處理一個新檔案的時候,FNR就從1開始計數,FNR可以理解為File Number of Record。


下面看兩個例子:


1,對於單個檔案NR 和FNR 的 輸出結果一樣的 :

# awk '{print NR,$0}' file1 
1 a b c d
2 a b d c
3 a c b d
#awk '{print FNR,$0}' file1 
1 a b c d
2 a b d c
3 a c b d


2,但是對於多個檔案 :

# awk '{print NR,$0}' file1 file2
1 a b c d
2 a b d c
3 a c b d
4 aa bb cc dd
5 aa bb dd cc
6 aa cc bb dd
# awk '{print FNR,$0}' file1 file2
1 a b c d
2 a b d c
3 a c b d
1 aa bb cc dd
2 aa bb dd cc
3 aa cc bb dd


NR和FNR的典型應用場景

現在有兩個檔案格式如下:

#cat account.data
張三|1
李四|2
#cat course.data
1|語文
1|數學
2|英語
2|化學


想要得到的結果是將使用者名稱,帳號和課程在同一行列印出來,如下:

張三|1|語文
張三|1|數學
李四|2|英語
李四|2|化學


執行如下程式碼

#awk -F \| 'NR==FNR{a[$2]=$0;next}{print a[$1]"|"$2}' account.data course.data


註釋:


由NR=FNR為真時,判斷當前讀入的是第一個檔案account.data,然後使用{a[$2]=$0;next}迴圈將account檔案的每行記錄都存入陣列a,並使用$2第2個欄位作為下標引用.


由NR=FNR為假時,判斷當前讀入了第二個檔案course.data,然後跳過{a[$2]=$0;next},對第二個檔案cdr的每一行都無條件執行{print a[$1]"|"$2},此時變數$1為第二個檔案的第一個欄位,與讀入第一個檔案時,採用第一個檔案第二個欄位$2為陣列下標相同.因此可以在此使用a[$1]引用陣列。


awk常用命令

1、列印檔案的第一列(域) : awk '{print $1}' filename

2、列印檔案的前兩列(域) : awk '{print $1,$2}' filename

3、列印完第一列,然後列印第二列 : awk '{print $1 $2}' filename

4、列印文字檔案的總行數 : awk 'END{print NR}' filename

5、列印文字第一行 :awk 'NR==1{print}' filename


相關文章