catflaps
catflaps

Reputation: 165

Update CSV file using AWK

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

Answers (2)

Akshay Hegde
Akshay Hegde

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

James Brown
James Brown

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

Related Questions