NR,表示awk開始執行程序後所讀取的數據行數.數組
FNR,與NR功用相似,不一樣的是awk每打開一個新文件,FNR便從0從新累計.bash
下面看兩個例子:blog
1,對於單個文件NR 和FNR 的 輸出結果同樣的 :get
# 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,可是對於多個文件 :class
# 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的典型應用:awk
如今有兩個文件格式以下:變量
#cat a 張三|000001 李四|000002 #cat b 000001|10 000001|20 000002|30 000002|15
想要獲得的結果是將用戶名,賬號和金額在同一行打印出來,以下:file
張三|000001|10
張三|000001|20
李四|000002|30
李四|000002|15循環
執行以下代碼引用
#awk -F \| 'NR==FNR{a[$2]=$0;next}{print a[$1]"|"$2}' a b
註釋:
由NR=FNR爲真時,判斷當前讀入的是第一個文件a,而後使用{a[$2]=$0;next}
循環將a文件的每行記錄都存入數組a,並使用$2第2個字段做爲下標引用.
由NR=FNR爲假時,判斷當前讀入了第二個文件b,而後跳過{a[$2]=$0;next},
對第二個文件cdr的每一行都無條件執行{print a[$1]"|"$2},
此時變量$1爲第二個文件的第一個字段,與讀入第一個文件時,採用第一個文件第二個字段$2爲數組下標相同.
所以能夠在此使用a[$1]引用數組。
=========================================================================
下面是CU大神jason680的詳細過程分析
awk -F'|' 'NR==FNR{a[$2]=$0;next}{print a[$1] FS $2}' a b
There is no BEGIN block, and FS="|" by -F'|' argument
沒有開始模塊,直接識別-F選項,加參數
start to first file 'a'
從a文件的第一行開始
1. read file a line 1 and get data 張三|000001
讀取文件a的第一行,獲得數據
A: $0=張三|000001
B: $1=張三
C: $2=000001
NR and FNR are the same equal to 1, and run NR=FNR block
此時,NR與FNR的值相等都爲1,執行NR=FNR模塊
NR==FNR{a[$2]=$0;next}
A: a[$2]=$0
a[000001]=張三|000001
B: next
next cycle and get next line data
2. read file a line 2 and get data 李四|000002
讀取文件a的第二行,獲得數據
A: $0=李四|000002
B: $1=李四
C: $2=000002
NR and FNR are the same equal to 2, and run NR=FNR block
此時,NR與FNR的值相等都爲1,執行NR=FNR模塊
NR==FNR{a[$2]=$0;next}
A: a[$2]=$0
a[000002]=李四|000002
B: next
next cycle and get next line data
end of the file a, and get next file b data
讀完文件a,而後讀取下一個文件b的數據
3. read file b line 1, and get data 000001|10
讀取文件b的第一行,而後獲得數據
A: $0=000001|10
B: $1=000001
C: $2=10
now, NR is 3 and FNR is 1, they are not eqaul
此時,NR與FNR的值不一樣,不執行NF=FNR模塊,執行下一個模塊{print a[$1] FS $2}
and didn't run NR=FNR block,
and run next block {print a[$1] FS $2}
a[$1] => a[000001] => 張三|000001
FS => |
$2 => 10
you will see the output
張三|000001|10
4. read file b line 2, and get data 000001|20
A: $0=000001|20
B: $1=000001
C: $2=20
NR is 4 and FNR is 2, they are not eqaul
and didn't run NR=FNR block,
and run next block {print a[$1] FS $2}
a[$1] => a[000001] => 張三|000001
FS => |
$2 => 20
you will see the output
張三|000001|20
cycle to read the file b
5. read file b line 3, and get data 000002|30
...
output==> 李四|000002|30
6. read file b line 4, and get data 000002|15 ... output==> 李四|000002|15