BEGIN { while (getline str > 0) printfields(str) } function printfields(str) { for (k=1; k<=csvsplit(str,arr); k++) print k, arr[k] } function csvsplit(str, arr, i,j,n,s,fs,qt) { # split comma-separated fields into arr # return number of fields in arr # in Europe, change fs from "," to ";" # fields surrounded by double-quotes may # contain commas; doubled double-quotes # represent a single embedded quote delete arr s = "START"; n = 0; fs = ","; qt = "\"" for (i = 1; i <= length(str); i++) { if (s == "START") { if (substr(str,i,1) == fs) { arr[++n] = "" } else if (substr(str,i,1) == qt) { j = i+1; s = "INQUOTES" } else { j = i; s = "INFIELD" } } else if (s == "INFIELD") { if (substr(str,i,1) == fs) { arr[++n] = substr(str,j,i-j) j = 0; s = "START" } } else if (s == "INQUOTES") { if (substr(str,i,1) == qt) { s = "MAYBEDOUBLE" } } else if (s == "MAYBEDOUBLE") { if (substr(str,i,1) == fs) { arr[++n] = substr(str,j,i-j-1) gsub(qt qt, qt, arr[n]) j = 0; s = "START" } } } if (s == "INFIELD" || s == "INQUOTES") { arr[++n] = substr(str,j) } else if (s == "MAYBEDOUBLE") { arr[++n] = substr(str,j,length(str)-j) gsub(qt qt, qt, arr[n]) } else if (s == "START") { arr[++n] = "" } return n }