Séparer une chaîne via des séparateurs, vers un tableau
Résolu
romegonic
Messages postés
28
Date d'inscription
Statut
Membre
Dernière intervention
-
romegonic Messages postés 28 Date d'inscription Statut Membre Dernière intervention -
romegonic Messages postés 28 Date d'inscription Statut Membre Dernière intervention -
Bonjour,
J'utilise korn shell sous AIX.
Mettons une chaîne de caractères (provenant d'une ligne d'un fichier, via sed) :
chaine='nom_1:valeur_1,nom_2:valeur_2,nom_3:valeur_3,nom_3:valeur_3'
Je souhaite parcourir cette chaîne et remplir un tableau, en indiquant comme délimiteur le ','
Comme cela j'embarque le nom et sa valeur et je me charge de tronquer le ':' pour utiliser ces deux champs.
L'idée est de pouvoir ensuite appeler tab[3], à savoir le nom_3 et sa valeur_3.
La difficulté supplémentaire réside dans le fait que la taille de la chaîne n'est bien sûr pas fixe, mais également le nombre ""d'enregistrements"".
Le taille du tableau ne peut donc pas être définie au préalable.
Si quelqu'un pouvait m'aider, je ne m'en sors pas avec seulement les expr sed cut awk tr habituels.
C'est surtout au niveau de la boucle que je galère, car il existe pas mal d'exemples concernant des fichiers en entrée, mais très peu concernant des chaînes (et je ne vais pas recopier ma chaîne dans un fichier ... qui ferait une ligne, ce qui n'apporterait rien ...)
Un while fin de chaîne ? Un for i in 'echo $chaine' do .. ?
Je vous remercie par avance pour vos éventuelles réponses.
J'utilise korn shell sous AIX.
Mettons une chaîne de caractères (provenant d'une ligne d'un fichier, via sed) :
chaine='nom_1:valeur_1,nom_2:valeur_2,nom_3:valeur_3,nom_3:valeur_3'
Je souhaite parcourir cette chaîne et remplir un tableau, en indiquant comme délimiteur le ','
Comme cela j'embarque le nom et sa valeur et je me charge de tronquer le ':' pour utiliser ces deux champs.
L'idée est de pouvoir ensuite appeler tab[3], à savoir le nom_3 et sa valeur_3.
La difficulté supplémentaire réside dans le fait que la taille de la chaîne n'est bien sûr pas fixe, mais également le nombre ""d'enregistrements"".
Le taille du tableau ne peut donc pas être définie au préalable.
Si quelqu'un pouvait m'aider, je ne m'en sors pas avec seulement les expr sed cut awk tr habituels.
C'est surtout au niveau de la boucle que je galère, car il existe pas mal d'exemples concernant des fichiers en entrée, mais très peu concernant des chaînes (et je ne vais pas recopier ma chaîne dans un fichier ... qui ferait une ligne, ce qui n'apporterait rien ...)
Un while fin de chaîne ? Un for i in 'echo $chaine' do .. ?
Je vous remercie par avance pour vos éventuelles réponses.
A voir également:
- Shell découper chaine caractère
- Caractère ascii - Guide
- Classic shell - Télécharger - Personnalisation
- Caractère spéciaux - Guide
- Caractères spéciaux : comment les saisir facilement - Guide
- Comment découper un pdf - Guide
5 réponses
Salut,
C'est obligé le ksh ? ;-\
Parce que sinon en bash :
J'utilise korn shell sous AIX.
C'est obligé le ksh ? ;-\
Parce que sinon en bash :
$ chaine='nom_1:valeur_1,nom_2:valeur_2,nom_3:valeur_3,nom_3:valeur_3'
$ echo "${chaine}"
nom_1:valeur_1,nom_2:valeur_2,nom_3:valeur_3,nom_3:valeur_3
$ tab=(${chaine//,/ })
$ echo ${tab[2]}
nom_3:valeur_3
$ echo ${tab[2]%:*}
nom_3
$ echo ${tab[2]#*:}
valeur_3
dindoun
Messages postés
1028
Date d'inscription
Statut
Membre
Dernière intervention
135
super je ne connaissais pas tab=(${chaine//,/ })
salut,
avec mksh, sur Debian
avec mksh, sur Debian
$ chaine='nom_1:valeur_1,nom_2:valeur_2,nom_3:valeur_3,nom_3:valeur_3'NB: les tableaux, par défaut, sont indexés à partir de zéro; donc, pour accéder au premier élément du tableau, il faut appeler
$ IFS=',' read -A tab <<<"$chaine"
$ printf '%s\n' "$tab[@]}"
nom_1:valeur_1
nom_2:valeur_2
nom_3:valeur_3
nom_3:valeur_3
"$tab[0]}";)
Merci pour vos réponses.
La première solution ne fonctionne pas sous ksh (dommage c'était clean et facile à manipuler ensuite).
Quant à la deuxième, je me prend une erreur (via set -xv) de syntaxe sur la ligne :
IFS=',' read -A tab <<<"$chaine"
IFS=',' read -A tab <<<"./aps.sh[23]: syntax error at line 23 : '<' unexpected
en gros il n'attend pas trois <<< successifs (et si j'en retire un cela ne fait plus rien)
Je continue à chercher via awk, en tous cas merci pour l'effort.
La première solution ne fonctionne pas sous ksh (dommage c'était clean et facile à manipuler ensuite).
Quant à la deuxième, je me prend une erreur (via set -xv) de syntaxe sur la ligne :
IFS=',' read -A tab <<<"$chaine"
IFS=',' read -A tab <<<"./aps.sh[23]: syntax error at line 23 : '<' unexpected
en gros il n'attend pas trois <<< successifs (et si j'en retire un cela ne fait plus rien)
Je continue à chercher via awk, en tous cas merci pour l'effort.
En reprenant l'exemple de qqchqcpQ et le même interpréteur (mksh) :
$ cat foo.mksh
#! /bin/mksh
chaine='nom_1:valeur_1,nom_2:valeur_2,nom_3:valeur_3,nom_4:valeur_4'
IFS=',' read -A tab <<<"$chaine"
i=0
for j in "${tab[@]}"
do
printf 'Nom = %s\tValeur = %s\n' "${tab[$i]%:*}" "${tab[$i]#*:}"
((i++))
done
$ ./foo.mksh
Nom = nom_1 Valeur = valeur_1
Nom = nom_2 Valeur = valeur_2
Nom = nom_3 Valeur = valeur_3
Nom = nom_4 Valeur = valeur_4
Vous n’avez pas trouvé la réponse que vous recherchez ?
Posez votre question
Bonjour,
J'ai finalement opté pour le code suivant, en utilisant des tableaux, comme je le souhaitais :
(auparavant j'ai chargé la chaîne de caractères dans la variable objet)
Et ceci est très pratique d'utilisation pour remplacer une valeur correspondant à un nom :-)
Sujet résolu, merci de votre aide :-)
J'ai finalement opté pour le code suivant, en utilisant des tableaux, comme je le souhaitais :
(auparavant j'ai chargé la chaîne de caractères dans la variable objet)
nb_att_objet='echo $objet | awk -F ',' '{ print NF }'' set -A attribut_nom; set -A attribut_valeur for i in 'seq 1 $nb_att_objet'; do attribut_nom[$i]='echo $objet | cut -d "," -f${i} | awk -F "\"" '{ print $2 }''; attribut_valeur[$i]='echo $objet | cut -d "," -f${i} | awk -F "\"" '{ print $4 }''; done
Et ceci est très pratique d'utilisation pour remplacer une valeur correspondant à un nom :-)
Sujet résolu, merci de votre aide :-)