Question

J'essaie d'écrire un script awk pour convertir une feuille de calcul au format CSV en XML pour les bogues Bugzilla. Le format du fichier CSV d'entrée est le suivant (créé à partir d'un tableur XLS et enregistré au format CSV):

tag_1,tag_2,...,tag_N
value1_1,value1_2,...,value1_N
value2_1,value2_2,...,value2_N
valueM_1,valueM_2,...,valueM_N

La colonne d'en-tête représente le nom de la balise XML. Le fichier ci-dessus converti en XML devrait ressembler à ceci:

<element>
    <tag_1>value1_1</tag_1>
    <tag_2>value1_2</tag_2>
    ...
    <tag_N>value1_N</tag_N>
</element>
<element>
    <tag_1>value2_1</tag_1>
    <tag_2>value2_2</tag_2>
    ...
    <tag_N>value2_N</tag_N>
</element>
...

Le script awk que je dois accomplir est le suivant:

BEGIN {OFS = "\n"}
NR == 1 {for (i = 1; i <=NF; i++)
            tag[i]=$i
         print "<bugzilla version=\"3.4.1\" urlbase=\"http://mozilla.com/\" maintainer=\"somebody@mozilla.com\" exporter=\"somebody.else@mozilla.com\">"}
NR != 1 {print "   <bug>"
         for (i = 1; i <= NF; i++)
            print "      <" tag[i] ">" $i "</" tag[i] ">"
         print "   </bug>"}
END {print "</bugzilla>"}

Le fichier CSV réel est:

cf_foo,cf_bar,short_desc,cf_zebra,cf_pizza,cf_dumpling ,assigned_to,bug_status,cf_word,cf_caslte
ABCD,A-BAR-0032,A NICE DESCRIPTION - help me,pretty,Pepperoni,,,NEW,,

La sortie réelle est:

$ awk -f csvtobugs.awk bugs.csv

<bugzilla version="3.4.1" urlbase="http://mozilla.com/" maintainer="somebody@mozilla.com" exporter="somebody.else@mozilla.com">
   <bug>
      <cf_foo,cf_bar,short_desc,cf_zebra,cf_pizza,cf_dumpling>ABCD,A-BAR-0032,A</cf_foo,cf_bar,short_desc,cf_zebra,cf_pizza,cf_dumpling>
      <,assigned_to,bug_status,cf_word,cf_caslte>NICE</,assigned_to,bug_status,cf_word,cf_caslte>
      <>DESCRIPTION</>
      <>-</>
      <>help</>
      <>me,pretty,Pepperoni,,,NEW,,</>
   </bug>
   <bug>
   </bug>
</bugzilla>

Clairement, ce n'est pas le résultat souhaité (je l'avoue, j'ai copié-collé ce script depuis ce forum: http://www.unix.com/shell-programming-scripting/21404-csv-xml.html ). Le problème, c’est que ça fait SOOOOO depuis longtemps que je ne regarde pas les scripts awk et je n’ai aucune idée de ce que la syntaxe signifie.

Était-ce utile?

La solution

Vous devez définir FS = " dans la règle BEGIN pour utiliser une virgule comme séparateur de champs; le code tel que vous le montrez devrait fonctionner si le séparateur de champs était un onglet, ce qui est une convention différente (aussi populaire) dans les fichiers souvent appelés "CSV". même les virgules ne sont pas utilisées; -).

Autres conseils

Utilisez un outil que vous connaissez bien:)

Ce script awk n'a pas l'air d'être traité avec " et autres bizarreries CSV. (Je pense que les divisions se divisent en onglets - comme le soulignent les autres réponses, il est nécessaire de changer de division en,) python, perl .Net, etc. ont des objets pour gérer complètement CSV et XML et vous pourriez probablement écrire la solution en quelques caractères seulement. comme le script awk et plus important encore le comprendre.

N'oubliez pas que le fractionnement par virgule dans un fichier CSV convient jusqu'à ce que le scénario suivant apparaisse:

1997,Ford,E350,"Super, luxurious truck"

Dans ce cas, il divisera "Super, camion luxueux". en deux éléments qui est incorrect. Je recommanderais d’utiliser les bibliothèques csv dans une autre langue comme "Mark" dans le post ci-dessus.

J'ai pu résoudre le problème en changeant le FS (séparateur de champs):

BEGIN {
    FS=",";
    OFS = "\n"}
NR == 1 {for (i = 1; i <=NF; i++)
            tag[i]=$i
         print "<bugzilla version=\"3.4.1\" urlbase=\"http://mozilla.com/\" maintainer=\"somebody@mozilla.com\" exporter=\"somebody.else@mozilla.com\">"}
NR != 1 {print "   <bug>"
         for (i = 1; i <= NF; i++)
            print "      <" tag[i] ">" $i "</" tag[i] ">"
         print "   </bug>"}
END {print "</bugzilla>"}

Sortie:

<bugzilla version="3.4.1" urlbase="http://mozilla.com/" maintainer="somebody@mozilla.com" exporter="somebody.else@mozilla.com">
   <bug>
      <cf_foo>ABCD</cf_foo>
      <cf_bar>A-BAR-0032</cf_bar>
      <short_desc>A NICE DESCRIPTION - help me</short_desc>
      <cf_zebra>pretty</cf_zebra>
      <cf_pizza>Pepperoni</cf_pizza>
      <cf_dumpling ></cf_dumpling >
      <assigned_to></assigned_to>
      <bug_status>NEW</bug_status>
      <cf_word></cf_word>
      <cf_caslte></cf_caslte>
   </bug>
</bugzilla>

Vous pouvez utiliser diverses astuces, telles que la configuration de FS. Plus de trucs peuvent être trouvés sur le groupe de news Awk. Il existe également des analyseurs comme le mien: http://lorance.freeshell.org/csv/

Vous pouvez essayer mon csvprintf . Il peut convertir CSV en XML, que vous pouvez ensuite styler avec XSLT à votre guise.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top