Separar una cadena mediante separadores, hacia una matriz
Resuelto
romegonic
Mensajes publicados
29
Estado
Miembro
-
romegonic Mensajes publicados 29 Estado Miembro -
romegonic Mensajes publicados 29 Estado Miembro -
Hola,
Estoy usando KornShell en AIX.
Pongamos una cadena de caracteres (proveniente de una línea de un archivo, vía sed):
cadena='nom_1:valor_1,nom_2:valor_2,nom_3:valor_3,nom_3:valor_3'
Quiero recorrer esta cadena y rellenar un arreglo, indicando como delimitador la ','.
Así voy a capturar el nombre y su valor y me encargo de truncar el ':' para usar estos dos campos.
La idea es poder después llamar tab[3], es decir el nom_3 y valor_3.
La dificultad adicional es que el tamaño de la cadena no es fijo, y tampoco el número de "registros" que contiene.
Por tanto, el tamaño del arreglo no puede definirse de antemano.
Si alguien pudiera ayudarme, no me manejo solo con los habituales sed, cut, awk, tr. Es sobre todo en la parte del bucle que estoy atascado, ya que hay muchos ejemplos para archivos de entrada, pero pocos para cadenas (y no voy a copiar mi cadena en un archivo... que fuera una sola línea, lo cual no aportaría nada...).
¿Un while fin de cadena? ¿Un for i in 'echo $cadena' do .. ?
Gracias de antemano por cualquier respuesta.
Configuración: Windows 7 / Chrome 33.0.1750.154
Estoy usando KornShell en AIX.
Pongamos una cadena de caracteres (proveniente de una línea de un archivo, vía sed):
cadena='nom_1:valor_1,nom_2:valor_2,nom_3:valor_3,nom_3:valor_3'
Quiero recorrer esta cadena y rellenar un arreglo, indicando como delimitador la ','.
Así voy a capturar el nombre y su valor y me encargo de truncar el ':' para usar estos dos campos.
La idea es poder después llamar tab[3], es decir el nom_3 y valor_3.
La dificultad adicional es que el tamaño de la cadena no es fijo, y tampoco el número de "registros" que contiene.
Por tanto, el tamaño del arreglo no puede definirse de antemano.
Si alguien pudiera ayudarme, no me manejo solo con los habituales sed, cut, awk, tr. Es sobre todo en la parte del bucle que estoy atascado, ya que hay muchos ejemplos para archivos de entrada, pero pocos para cadenas (y no voy a copiar mi cadena en un archivo... que fuera una sola línea, lo cual no aportaría nada...).
¿Un while fin de cadena? ¿Un for i in 'echo $cadena' do .. ?
Gracias de antemano por cualquier respuesta.
Configuración: Windows 7 / Chrome 33.0.1750.154
5 respuestas
-
Hola,
Estoy usando Korn shell en AIX.
¿Es obligatorio ksh? ;-\
Porque si no en bash:
$ cadena='nom_1:valor_1,nom_2:valor_2,nom_3:valor_3,nom_3:valor_3'
$ echo "${cadena}"
nom_1:valor_1,nom_2:valor_2,nom_3:valor_3,nom_3:valor_3
$ tab=(${cadena//,/ })
$ echo ${tab[2]}
nom_3:valor_3
$ echo ${tab[2]%:*}
nom_3
$ echo ${tab[2]#*:}
valor_3
--
Zen mes nuggets ;-)
Faites un geste pour l'environnement, fermez vos fenêtres et adoptez un manchot. <('') -
hola,
con mksh, en 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]}"
;) -
Gracias por vuestras respuestas.
La primera solución no funciona bajo ksh (una lástima, era limpia y fácil de manipular después).
En cuanto a la segunda, me encuentro con un error (con set -xv) de sintaxis en la línea:
IFS=',' read -A tab <<<"$chaine"
IFS=',' read -A tab <<<"./aps.sh[23]: syntax error at line 23 : '<' unexpected
en resumen no espera tres <<< de forma consecutiva (y si quito uno ya no hace nada)
Sigo buscando a través de awk, en cualquier caso gracias por el esfuerzo. -
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
--
Zen my nuggets ;-)
Faites un geste pour l'environnement, fermez vos fenêtres et adoptez un manchot. <('') -
Hola, He acabado optando por el siguiente código, utilizando tablas, como quería: (anteriormente cargué la cadena en la variable objeto)
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 }''; doneY esto es muy práctico para reemplazar un valor que corresponde a un nombre :-) Asunto resuelto, gracias por tu ayuda :-)