From this question, I answer with this solution:
awk 'FNR==NR{a[FNR]=$2;next}{$NF=a[FNR]}1' file2 file1
It works as expected.
But the first solution I thought is:
$ awk 'FNR==NR{a[FNR]=$2;next}$NF=a[FNR]' file2 file1
A 63 9 6
B 45 3 5
It does not work, since when awk
had not print the first line in file1
. It make me suprise, and don't know why awk
skip the first line.
Here is some examples:
$ awk 'FNR==NR{next}$1=123' file2 file1
123 23 8 T
123 63 9 9
123 45 3 J
$ awk 'FNR==NR{a[FNR]=$2;next} FNR in a' file2 file1
A 23 8 T
A 63 9 9
B 45 3 J
You can see, from both examples, awk
works as expected. First assigning new value to a field of current record affected record value, and awk
print new value. The second show that awk
had process all record in file2
, no record is skipped.
Why awk
skip the first line in my first solution?
I use gawk 4.0.1
, and also tested with mawk 1.3.3
.
Best Answer
You have:
as the final condition (the one that determines whether to print). Assignments return the value assigned, in this case
a[FNR]
. The first line of the data file from the linked question is:a[FNR]
is initialised to$2
. That means the value ofa[FNR]
is0
, which is a false value to awk. That means the assignment is false, which makes the conditional false and suppresses the default printing behaviour. If we change the data file to:then the first line will be printed, but the last one will be missing.
So it's not that the first line is absent, it's any line where the last field is zero (or empty). It just happens that the first line and only the first line was like that.