2012-09-06 17 views
10

Estoy intentando recorrer una matriz que contiene otras matrices y estas matrices están formadas por cadenas con espacios. El problema es que parece que no puedo conservar el espacio en la cuerda. La cadena con espacios están bien dividida en varios elementos, si cambio de IFS para \ n o todos los elementos de la matriz son vistos como 1 punto si dejo IFS sin cambios aquí algunos ejemplos de código:Recorrido por una matriz de matrices de cadenas con espacios

#!/bin/sh 
low1=("AA QQ" "BB LL") 
low2=("CC" "DD") 
low3=("EE" "FF") 
high=(low1 low2 low3) 

for high_item in ${high[@]} 
do 
    eval arrayz=\${$high_item[@]} 
    #IFS=$'\n' 
    for item in $arrayz 
    do 
     echo $item 
    done 
done 

Salida:

 
AA 
QQ 
BB 
LL 
CC 
DD 
EE 
FF 

Como puede ver, los elementos "AA QQ" y "BB LL" se han dividido.

Si descomentar la línea que establece IFS a \n consigo el siguiente:

 
AA QQ BB LL 
CC DD 
EE FF 

Ahora "QQ AA" y "BB LL" se concatenan!

¿Hay alguna forma de preservar estos elementos al igual que originales se ... Necesito la salida para que parezca que:

 
AA QQ 
BB LL 
CC 
DD 
EE 
FF 
+0

Para 'low1', tiene cada elemento en una línea separada. Para 'low2' y' low3', todos los elementos aparecen en una sola línea.Es esto intencional? – chepner

Respuesta

4

Reemplazar eval con la expansión de parámetros indirectos, y obtendrá lo que piensa que quiere (aunque no coincide con la corriente de salida dada:.

for high_item in "${high[@]}" 
do 
    arrayz="$high_item[@]" 
    # arrayz is just a string like "low1[@]" 
    for item in "${!arrayz}" 
    do 
     echo $item 
    done 
done 

Nota necesidad de citar la expansión del array en el bucle interno para conservar el espacio en blanco en elementos de low1

5

creo que quería decir que la salida debe ser similar:

AA QQ 
BB LL 
CC 
DD 
EE 
FF 

es decir:

${low1[0]} 
${low1[1]} 
${low2[0]} 
${low2[1]} 
${low3[0]} 
${low3[1]} 

Esto podría lograrse usando:

#!/bin/bash 

low1=("AA QQ" "BB LL") 
low2=("CC" "DD") 
low3=("EE" "FF") 
high=(low1 low2 low3) 

for high_item in ${high[@]} 
do 
    x="${high_item}[@]" # -> "low1[@]" 
    arrays=("${!x}") 

    #IFS=$'\n' 
    for item in "${arrays[@]}" 
    do 
     echo "$item" 
    done 
done 

Y favor utilice siempre #!/bin/bash para scripts bash.

Explicación: ${!x} es expansión de variable indirecta. Evalúa el valor de la variable con un nombre que figura en $x.

Para nuestras necesidades, x necesita tener el sufijo [@] para expansión de matriz también. Tenga en cuenta especialmente que es x=${high_item}[@] y nox=${high_item[@]}.

Y usted tiene que evaluarlo en el contexto de matriz; de lo contrario, no funcionaría como se esperaba (si lo hace arrays=${!x}).

Ah, y como nota final: IFS no hace ninguna diferencia aquí. Siempre que trabaje en matrices con comillas, IFS no entra en juego.

Cuestiones relacionadas