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   -
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.


A voir également:

5 réponses

zipe31 Messages postés 36402 Date d'inscription   Statut Contributeur Dernière intervention   6 431
 
Salut,

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
1
dindoun Messages postés 1028 Date d'inscription   Statut Membre Dernière intervention   135
 
super je ne connaissais pas tab=(${chaine//,/ })
1
Utilisateur anonyme
 
salut,

avec mksh, sur Debian
$ chaine='nom_1:valeur_1,nom_2:valeur_2,nom_3:valeur_3,nom_3:valeur_3'
$ 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
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
"$tab[0]}"
;)
0
Utilisateur anonyme
 
une 'tite correction :
"${tab[0]}"
: 'manquait une accolade, ouf.
0
romegonic Messages postés 28 Date d'inscription   Statut Membre Dernière intervention  
 
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.
0
zipe31 Messages postés 36402 Date d'inscription   Statut Contributeur Dernière intervention   6 431
 
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

0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
romegonic Messages postés 28 Date d'inscription   Statut Membre Dernière intervention  
 
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)

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 :-)
0