NR indicates the number of data rows read after the awk starts executing the program.
FNR is similar to Nr. The difference is that FNR accumulates from 0 every time awk opens a new file.
The following are two examples:
1. The output results for a single file NR and FNR are the same:
# 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, but for multiple files:
# 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 |
Let's look at another example of typical application of NR and FNR:
There are two file formats:
# Cat account James | 000001 Li Si | 000002 # Cat CDR 000001 | 10 000001 | 20 000002 | 30 000002 | 15 |
The result is to print the username, account, and amount in the same line, as shown below:
Michael Jacob | 000001 | 10 Michael Jacob | 000001 | 20 Lee IV | 000002 | 30 Li Si | 000002 | 15 |
Run the following code:
# Awk-F/| 'nr = FNR {A [$2] = $0; next} {print a [$1] "|" $2} 'account CDR |
Note:
When Nr = FNR is true, the first file account is read, and then {A [$2] = $0; next} cyclically stores each row of the account file into array A, and uses $2 2nd fields as subscript reference.
When Nr = FNR is false, judge that the second file CDR is read, and skip {A [$2] = $0; next }, execute {print a [$1] "|" $2} unconditionally for each row of the Second file Cdr. At this time, the variable $1 is the first field of the Second file, when reading the first file, the second field $2 of the first file is used as the array subscript. therefore, you can use a [$1] to reference arrays here.