Reputation: 165
I'm trying to write an AWK script to update a csv file with values for a new csv file, such that the details are updated for existing rows, but rows not present in the new csv are kept. I think it can be done by making an index with (NR == FNR), but I haven't managed to get anything to work yet. Here is so it is supposed to work:
old.csv
Name Size Date
==================
A 20mb 1/10
B 10mb 1/10
new.csv
Name Size Date
==================
A 24mb 2/10
C 30mb 2/10
(Some script, possibly AWK?)
output.csv
Name Size Date
==================
A 24mb 2/10
B 10mb 1/10
C 30mb 2/10
Any ideas on how to achieve this? Can possibly use something other than AWK, but it has to work on a minimal AIX setup
Thanks
Upvotes: 0
Views: 754
Reputation: 16997
$ cat old
Name Size Date
==================
A 20mb 1/10
B 10mb 1/10
$ cat new
Name Size Date
==================
A 24mb 2/10
C 30mb 2/10
$ awk 'FNR<3{if(FNR==NR)print;next}{a[$1]=$0}END{for(i in a)print a[i]}' old new
Name Size Date
==================
A 24mb 2/10
B 10mb 1/10
C 30mb 2/10
Explanation
awk '
FNR<3{ # this is for skipping first 2 lines
if(FNR==NR)print; # FNR==NR is true only when awk reads first file
next # go to next line
}
{
a[$1]=$0 # array a where index being first field and value being current record/line/row
}
END{ # end block we print array a contents
for(i in a)print a[i]
}
' old new
Upvotes: 2
Reputation: 37394
In awk. Read all old records in an array a
, while printing new ones delete
matching old ones from a
and in the END
print any existing old ones:
$ awk 'NR==FNR{a[$1]=$0;next}{print $0;delete a[$1]}END{for(i in a) print a[i]}' old new
Name Size Date
==================
A 24mb 2/10
C 30mb 2/10
B 10mb 1/10
Order will be lost.
Upvotes: 1