Подтвердить что ты не робот

Выход из разделителя в двойных кавычках, в awk

Я использую awk для анализа моих данных с помощью "," как разделителя, так как вход представляет собой файл csv. Однако в данных, которые избегаются двойными кавычками ( "..." ), есть "," .

Пример

filed1,filed2,field3,"field4,FOO,BAR",field5

Как я могу игнорировать запятую "," внутри двойной кавычки, чтобы я мог правильно разобрать вывод с помощью awk? Я знаю, что мы можем сделать это в Excel, но как это сделать в awk?

4b9b3361

Ответ 1

Для очень подробного описания смотрите здесь:

http://backreference.org/2010/04/17/csv-parsing-with-awk/ (версия archive.org)

Но это не синтаксический анализ, а обман с регулярным выражением. Для чего-либо более сложного, чем примеры на странице, вы должны использовать Perl/Python с библиотекой синтаксического анализатора, например, "csv" для Python.

Ответ 2

Это просто, с GNU awk 4:

zsh-4.3.12[t]% awk '{ 
 for (i = 0; ++i <= NF;)
   printf "field %d => %s\n", i, $i
 }' FPAT='([^,]+)|("[^"]+")' infile
field 1 => filed1
field 2 => filed2
field 3 => field3
field 4 => "field4,FOO,BAR"
field 5 => field5

Добавление некоторых комментариев согласно требованию OP.

Из руководства по GNU awk "Определение полей по содержанию":

Значение FPAT должно быть строкой, предоставляющей регулярное выражение. Это регулярное выражение описывает содержимое каждого поля. В случае данных CSV, представленных выше, каждое поле представляет собой либо "все, что не является запятой", либо "двойную кавычку, все, что не является двойной кавычкой и закрывающей двойной кавычкой". Если бы записать как константу регулярного выражения, мы бы имели /([^,]+)|("[^"]+")/. Запись этого в виде строки требует от нас избежать двойных кавычек, приводящих к:

FPAT = "([^,]+)|(\"[^\"]+\")"

Использование + дважды, это не работает должным образом для пустых полей, но это также можно исправить:

Как написано, регулярное выражение, используемое для FPAT, требует, чтобы каждое поле содержало хотя бы один символ. Простая модификация (изменение первого ' + на' *) позволяет пустым полям:

FPAT = "([^,]*)|(\"[^\"]+\")"

Ответ 3

FPAT работает, когда в цитированных полях есть символы новой строки и запятые, но не когда есть двойные кавычки, например:

field1,"field,2","but this field has ""escaped"" quotes"

Вы можете использовать простую программу-оболочку, которую я написал, называемую csvquote, чтобы упростить чтение данных awk, а затем восстановить проблемные специальные символы, например:

csvquote inputfile.csv | awk -F, '{print $4}' | csvquote -u

См. https://github.com/dbro/csvquote для кода и документов

Ответ 4

Полноценные синтаксические анализаторы CSV, такие как Perl Text::CSV_XS, предназначены для обработки такого рода странности.

Предположим, вы хотите только напечатать 4-е поле:

perl -MText::CSV_XS -lne 'BEGIN{$csv=Text::CSV_XS->new()} if($csv->parse($_)){ @f=$csv->fields(); print "\"$f[3]\"" }' file

Входная строка разделяется на массив @f
Поле 4 является $f[3], поскольку Perl начинает индексирование при 0

В моем ответе я дал больше объяснений Text::CSV_XS: проанализировать файл csv с помощью gawk