Since I am learning awk
; I found out FNR==NR
approach is a very common method to process two files. If FNR==NR
; then it is the first file
, when FNR
reset to 1
while reading every line from concatenated files it means !(FNR==NR)
and it is obviously the second file
.
When it comes to three or more files I can't see a way which is second and third file as both have the same !(FNR==NR)
condition. This made me to try to figure out how can there be something like FNR2
and FNR3
?
So I implemented a method to process three files in one awk
. Assuming like there is FNR1
FNR2
FNR3
for each file. For every file I made for loop
that runs seperately. Condition is same for every loop NR==FNR#
and actually get what I expected:
So I wonder if there are more sober, concise methods that deliver similar results with belowawk
code
Sample File Contents
$ cat file1
X|A1|Z
X|A2|Z
X|A3|Z
X|A4|Z
$ cat file2
X|Y|A3
X|Y|A4
X|Y|A5
$ cat file3
A1|Y|Z
A4|Y|Z
AWK for loop
$ cat fnrarray.sh
awk -v FS='[|]' '{ for(i=FNR ; i<=NR && i<=FNR && NR==FNR; i++) {x++; print "NR:",NR,"FNR1:",i,"FNR:",FNR,"\tfirst file\t"}
for(i=FNR ; i+x<=NR && i<=FNR && NR==FNR+x; i++) {y++; print "NR:",NR,"FNR2:",i+x,"FNR:",FNR,"\tsecond file\t"}
for(i=FNR ; i+x+y<=NR && i<=FNR && NR==FNR+x+y; i++) {print "NR:",NR,"FNR3:",i+x+y,"FNR:",FNR,"\tthird file\t"}
}' file1 file2 file3
Current and desired output
$ sh fnrarray.sh
NR: 1 FNR1: 1 FNR: 1 first file
NR: 2 FNR1: 2 FNR: 2 first file
NR: 3 FNR1: 3 FNR: 3 first file
NR: 4 FNR1: 4 FNR: 4 first file
NR: 5 FNR2: 5 FNR: 1 second file
NR: 6 FNR2: 6 FNR: 2 second file
NR: 7 FNR2: 7 FNR: 3 second file
NR: 8 FNR3: 8 FNR: 1 third file
NR: 9 FNR3: 9 FNR: 2 third file
You can see NR
is aligning with FNR#
and it is readable which NR
is for which file#
.
Another Method
I found this method FNR==1{++f} f==1 {}
here Handling 3 Files using awk
But this method is replacing arr1[1]
when new line is read every time
Fail attempt 1
$ awk -v FS='[|]' 'FNR==1{++f} f==1 {split($2,arr); print arr1[1]}' file1 file2 file3
A1
A2
A3
A4
Success with for loop (arr1[1]
is not changed)
$ awk -v FS='[|]' '{for(i=FNR ; i<=NR && i<=FNR && NR==FNR; i++) {arr1[++k]=$2; print arr1[1]}}' file1 file2 file3
A1
A1
A1
A1