Forum Programmation.shell IFS= et imbrication

Posté par . Licence CC By‐SA.
Étiquettes : aucune
0
16
jan.
2015

Bonjour,

J'ai un fichier CSV avec des lignes du genre :

AEQF;bla;bli;blu;ju;jo;toto;foo|bar|baz
SEQI;hik;hop;kii;ji;ju;titi;fii|gii|hop

Je souhaite parcourir chaque ligne, mettre chaque champ dans un tableau et traiter le dernier champ de manière particulière en le « splitant » à son tour. Voici le code :

# Boucle sur le tableau "lines", pour chaque élément définition d'un tableau "fields"
for l in "${lines[@]}"
 do
 while IFS=';' read -a fields
 do
 case "${fields[0]}" in
 "AEQF")
 while IFS='|' read -a hostgroups
 do
 for hg in "${hostgroups[@]}"
 do
 echo "HG;ADD;${hg};${hg}";
 done
 done <<< "${fields[7]}"
 echo "HOST;ADD;${fields[2]};${fields[4]};${fields[3]};${fields[6]};${fields[1]};${fields[7]}"
 ;;
 "SEQI")
 echo "HOST;DEL;${fields[2]}"
 ;;
 *)
 echo "Problem!"
 ;;
 esac
 done <<< "$l"
done

Certains se seront peut-être rendu compte qu'en fait je m'efforce de générer un fichier que CLAPI (Centreon Command Line API) pourra importer, à partir de fichiers CSV générés par un outil maison...

Mon problème est que si la valeur d'un champ possède des espaces ça ne fonctionne pas :(

[stef@459ETU1 ]# cat test1
AEQF;bla;bli;blu;ju;jo;toto;foo|bar|baz
SEQI;hik;hop;kii;ji;ju;titi;fii|gii|hop
[stef@459ETU1 ]# cat test2
AEQF;bla bla;bli;blu;ju;jo;toto;foo|bar|baz
SEQI;hik;hop;kii;ji;ju;titi;fii|gii|hop
[stef@459ETU1 ]# ./clapi_import.sh test1
HG;ADD;foo;foo
HG;ADD;bar;bar
HG;ADD;baz;baz
HOST;ADD;bli;ju;blu;toto;bla;foo|bar|baz
HOST;DEL;hop
[stef@459ETU1 ]# ./clapi_import.sh test2
HOST;ADD;;;;;bla;
Problem!
HOST;DEL;hop
[stef@459ETU1 ]#

Au départ, à la place des

while IFS=';' read -a toto
 do
 ...
 done <<< "$var"

j'avais utilisé des

IFS=';' && fields=($var)

mais le problème est le même.

Une idée ?

Je suis bien entendu ouvert à toute proposition, je ne tiens pas plus que ça à réussir à imbriquer des IFS= :) Donc d'une manière générale, comment doit-on appréhender ces fichiers CSV avec « deux niveaux de séparateurs » en bash (3.2.25) ? En plus à foutre tout ça dans un case, comment dire... je sens que je me fourvoie !

  • # Réponse à moi même

    Posté par . Évalué à 3.

    J'aurais dû poster le script en entier tiens :/ En fait je me rends compte que le problème est en amont...

    Le fait que j'arrive au cas *) c'est certainement que le problème survient au moment de la création de mon tableau lines :|

    Bon ben vu que c'est le week-end je verrai ça lundi :)

  • # Awk ?

    Posté par . Évalué à 2.

    Hello,

    si tu ne t'interdis pas Awk, 15 lignes de script pourraient faire l'affaire (enfin, si j'ai bien compris le résultat à atteindre !) :

    #! /usr/bin/awk -f
    BEGIN {
     FS=";"
     OFS=";"
    }
    $1 ~ /AEQF/ {
     split($NF, Array, "|");
     for (hg in Array)
     {
     print "HOST;ADD", Array[hg], Array[hg]
     }
     print "HOST;ADD",$3,$5,$4,$7,$2,$8
    }
    $1 ~ /SEQI/ {
     print "HOST;DEL",$3
    }

    Chez moi, le script clapi_import.awk donne ça :

    ./clapi_import.awk sample.txt sample2.txt
    HOST;ADD;foo;foo
    HOST;ADD;bar;bar
    HOST;ADD;baz;baz
    HOST;ADD;bli;ju;blu;toto;bla;foo|bar|baz
    HOST;DEL;hop
    HOST;ADD;foo;foo
    HOST;ADD;bar;bar
    HOST;ADD;baz;baz
    HOST;ADD;bli;ju;blu;toto;bla bla;foo|bar|baz
     #^^^^^^^ L'espace est bien repris
    HOST;DEL;hop

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.