Цель этого вопроса - предоставить канонический ответ.
Учитывая CSV, который может быть сгенерирован Excel или другими инструментами со встроенными новыми строками, встроенными двойными кавычками и пустыми полями, например:
$ cat file.csv
"rec1, fld1",,"rec1"",""fld3.1
"",
fld3.2","rec1
fld4"
"rec2, fld1.1
fld1.2","rec2 fld2.1""fld2.2""fld2.3","",rec2 fld4
Какой наиболее надежный способ эффективно использовать awk для идентификации отдельных записей и полей:
Record 1:
$1=<rec1, fld1>
$2=<>
$3=<rec1","fld3.1
",
fld3.2>
$4=<rec1
fld4>
----
Record 2:
$1=<rec2, fld1.1
fld1.2>
$2=<rec2 fld2.1"fld2.2"fld2.3>
$3=<>
$4=<rec2 fld4>
----
поэтому он может использоваться как те записи и поля внутри остальной части awk script.
Действительным CSV будет тот, который соответствует RFC 4180 или может быть сгенерирован MS-Excel.
Решение должно терпеть конец записи, просто являющийся LF (\n
), что характерно для файлов UNIX, а не CRLF (\r\n
), как этого требует стандарт, и Excel или другие инструменты Windows будут генерировать. Он также переносит некотируемые поля, смешанные с указанными полями. В частности, не нужно допускать экранирование "
с предыдущей обратной косой чертой (т.е. \"
вместо ""
), как позволяют некоторые другие форматы CSV - если у вас есть, то добавление перед ним gsub(/\\"/,"\"\"")
будет обрабатывать и пытаться чтобы автоматически обрабатывать оба механизма экранирования в одном script, сделало бы script излишне хрупким и сложным.