Для столь же простого входного файла, как вы, вы можете просто написать небольшую функцию для преобразования всех реальных FS вне кавычек в какое-то другое значение (я выбрал RS, поскольку разделитель записей не может быть частью записи), а затем используйте это как FS, например:
$ cat decsv.awk
BEGIN{ fs=FS; FS=RS }
{
decsv()
for (i=1;i<=NF;i++) {
printf "Record %d, Field %d is <%s>\n" ,NR,i,$i
}
print ""
}
function decsv( curr,head,tail)
{
tail = $0
while ( match(tail,/"[^"]+"/) ) {
head = substr(tail, 1, RSTART-1);
gsub(fs,RS,head)
curr = curr head substr(tail, RSTART, RLENGTH)
tail = substr(tail, RSTART + RLENGTH)
}
gsub(fs,RS,tail)
$0 = curr tail
}
$ cat file
id, name, value
1, foo, 17
2, bar, 76
3, "I am the, question", 99
$ awk -F", " -f decsv.awk file
Record 1, Field 1 is <id>
Record 1, Field 2 is <name>
Record 1, Field 3 is <value>
Record 2, Field 1 is <1>
Record 2, Field 2 is <foo>
Record 2, Field 3 is <17>
Record 3, Field 1 is <2>
Record 3, Field 2 is <bar>
Record 3, Field 3 is <76>
Record 4, Field 1 is <3>
Record 4, Field 2 is <"I am the, question">
Record 4, Field 3 is <99>
Это становится только сложным, когда вам приходится иметь дело со встроенными символами новой строки и встроенными экранированными кавычками внутри кавычек, и даже тогда это не так уж сложно, и все это было сделано раньше ...
См. Какой самый надежный способ эффективного анализа CSV с использованием awk? для получения дополнительной информации.