web-dev-qa-db-fra.com

Échappement du séparateur entre guillemets doubles, en awk

J'utilise awk pour analyser mes données avec "," en tant que séparateur car l'entrée est un fichier csv. Cependant, il y a "," dans les données qui est échappé par des guillemets doubles ("...").

Exemple

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

Comment puis-je ignorer la virgule "," dans la citation double afin que je puisse analyser correctement la sortie à l'aide de awk? Je sais que nous pouvons le faire dans Excel, mais comment pouvons-nous le faire dans awk?

26
joomanji

C'est simple, avec 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

Ajout de commentaires selon les exigences du PO.

Depuis le GNU manuel de awk :

La valeur de FPAT doit être une chaîne fournissant un .__ régulier. expression. Cette expression régulière décrit le contenu de chaque champ. Dans le cas des données CSV telles que présentées ci-dessus, chaque champ est soit “tout ce qui n'est pas une virgule”, soit “une double citation, n'importe quoi ce n'est pas une citation double, et une citation double de clôture. ”Si écrit en tant que une expression régulière constante (voir Chapitre 3 [Expressions rationnelles], page 37), nous aurions/([^,] +) | ("[^"] + ") /. Écrire ceci sous forme de chaîne nécessite que nous échappions aux guillemets doubles, ce qui conduit à: FPAT = "([^,] +) | (\" [^\"] + \") "

21
Dimitre Radoulov

FPAT fonctionne lorsqu'il y a des sauts de ligne et des virgules dans les champs cités, mais pas lorsqu'il y a des guillemets doubles, comme ceci:

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

Vous pouvez utiliser un programme d'encapsulation simple que j'ai écrit appelé csvquote pour rendre les données faciles à interpréter par awk, puis restaurer les caractères spéciaux problématiques, comme ceci:

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

Voir https://github.com/dbro/csvquote pour le code et la documentation.

11
D Bro