How can I transform a CSV file to a TOML hash table using AWK

386 views Asked by At

I want to use AWK to transform a CSV file to TOML. My input looks like this:

id , name , lifetime   
adam , Adam , 1550-1602
eve , Eve , 1542-1619

and I'm trying to get to this

[adam]
  name = "Adam"
  lifetime = "1550-1602"
[eve]
  name = "Eve"
  lifetime = "1542-1619"

I made the following little AWK script, which doesn't quite make it:

BEGIN {
  FS=","
  }
NR == 1 {
  nc = NF
  for (c = 1; c <= NF; c++) {
    h[c] = $c
    }
  }
NR > 1 {
  for(c = 1; c <= nc; c++) {
    printf h[c] "= " $c "\n"
    }
    print ""
   }
END {    
  }

The result so far is this

id = adam
 name =  Adam 
 lifetime=  1550-1602

id = eve 
 name =  Eve 
 lifetime=  1542-1619

For the record my version of AWK is GNU Awk 4.1.4

1

There are 1 answers

0
RavinderSingh13 On BEST ANSWER

Could you please try following, written and tested with shown samples in GNU awk.

awk -F'[[:space:]]*,[[:space:]]*' -v s1="\"" '
FNR==1{
  for(i=2;i<=NF;i++){
    gsub(/^ +| +$/,"",$i)
    arr[i]=$i
  }
  next
}
{
  print "["$1"]"
  for(i=2;i<=NF;i++){
    print "  "arr[i]" = "s1 $i s1
  }
}' Input_file

Explanation: Adding detailed explanation for above solution.

awk -F'[[:space:]]*,[[:space:]]*' -v s1="\"" '    ##Starting awk program from here, setting field separator as space comma space and creating variable s1 which has " in it.
FNR==1{                                           ##Checking condition if this is first line then do following.
  for(i=2;i<=NF;i++){                             ##Run a for loop from 2nd field to last field in current line.
    gsub(/^ +| +$/,"",$i)                         ##Globally substituting spaces from starting or ending to NULL in current field.
    arr[i]=$i                                     ##Creating arr with index of i and value of $i here.
  }
  next                                            ##next will skip all further statements from here.
}
{
  print "["$1"]"                                  ##Printing [ first field ] here.
  for(i=2;i<=NF;i++){                             ##Running loop from 2 to till last field of line here.
    print "  "arr[i]" = "s1 $i s1                 ##Printing arr value with index i and s1 current field s1 here.
  }
}' Input_file                                     ##Mentioning Input_file name here.

NOTE: OP's sample Input_file was having spaces in first line to remove them gsub(/^ +| +$/,"",$i) is being used remove this if no spaces are found at last of 1st line of Input_file.