2012-05-08 23 views
8

Dos cosas, primero esta es mi primera pregunta en este foro y me disculpo si el formateo está por todos lados. En segundo lugar, no he escrito tantos scripts bash, y suele pasar bastante tiempo entre los scripts que produzco.

Dicho esto, esta es mi pregunta.

¿Es posible hacer algo como esto en bash (Claro arreglo $ array contiene):
$array=()

Básicamente esto es lo que me gustaría hacer. Tengo una variable con nombres de variable de matriz en ella:

array1=() 
array2=() 
arrayList="array1 array2" 


# In a function far far away 
for array in $arrayList 
do 
    eval arr=("\"\${$array[@]\"") 

    for index in ${!arr[@]} 
    do 
     echo "${arr[$index]}" 
    done 
    # Here is the big "?", I like to clear the array that $array refers to. 
    $array=() 
done 

Mis matrices contienen cadenas que incluyen "" (espacio) y es por eso que utilizo la declaración eval. No estoy seguro de que sea necesario, pero al menos está funcionando. El script funciona más o menos como yo quiero, pero necesito borrar las matrices en el $arrayList, y prefiero no codificarlo en alguna parte, aunque sería fácil.

Gracias de antemano.

+0

Ver http://mywiki.wooledge.org/BashFAQ/048 re: el uso de eval - la forma abreviada es que realmente no es una práctica recomendada. –

+0

¡Gracias por el enlace! Leí que 'eval 'no es una forma recomendable de hacerlo, ya que puedes inyectar cosas malas en él, o incluso hacer algunas cosas estúpidas si no tienes cuidado con lo que" evelles ". Consideraré cambiarlo por otra solución, aunque este script solo lo usaré yo. – Qben

+0

Quizás lo que realmente quieres son matrices asociativas. Están disponibles en bash 4. – Dunes

Respuesta

11

Probablemente la cosa más simple de hacer es solo unset. Una variable unset actuará de manera idéntica a una matriz vacía en la mayoría de contextos, y unset $array debería funcionar bien.

+0

¿Quieres decir que podría ser así de fácil? :) Pensé que simplemente desarmaría la variable $ array dejando $ array1 y $ array2 intactos.Pero después de probar tu sugerencia parece prometedor. ¡Gracias un montón! – Qben

+0

@Qben 'unset array' desarmaría la variable de matriz en sí; 'unset $ array' funciona según lo anunciado. –

+0

@Qben: Cuando "desajuste" de forma indirecta, recomiendo citar la variable: "unset" $ array "' –

1

No se puede hacer $foo=barvez - No es así como indirecta asignaciones en el trabajo bash. Desafortunadamente, aunque poder hacer asignaciones indirectas de matriz es una función disponible en ksh93, no es una función disponible formalmente documentada en bash.

Citando BashFAQ #6 (que debe ser leído en su totalidad si usted está interesado en saber más sobre el uso de variables indirectas en general):

No tenemos conocimiento de cualquier truco que puede duplicar esa funcionalidad en POSIX o Bourne shells (menos que el uso de eval, que es extremadamente difícil de hacer de forma segura). Bash casi puede hacerlo: algunos trucos de matriz indirectos funcionan, y otros no, y no sabemos si la sintaxis involucrada se mantendrá estable en lanzamientos futuros. Por lo tanto, considere esto un uso en su propio riesgo de pirateo.

# Bash -- trick #1. Seems to work in bash 2 and up. 
realarray=(...) ref=realarray; index=2 
tmp="$ref[$index]" 
echo "${!tmp}"   # gives array element [2] 

# Bash -- trick #2. Seems to work in bash 3 and up. 
# Does NOT work in bash 2.05b. 
tmp="$ref[@]" 
printf "<%s> " "${!tmp}"; echo # Iterate whole array. 

Sin embargo, la limpieza es más sencilla, ya que unset $array va a funcionar bien.

+0

No creo que quiera desreferenciar, solo quiere vaciar el arreglo – c00kiemon5ter

+0

@ c00kiemon5ter seguro, pero pero respondiendo solo cómo vaciar una matriz dejará a alguien preguntándose cada vez que intente hacer otra cosa. He agregado una respuesta directa, pero creo que es valioso responder a la pregunta más amplia de "¿qué debo hacer en vez de' $ array = ... '"? –

+0

Las asignaciones indirectas se pueden hacer de esta manera: 'declare $ foo = bar' –

-1
array=() 

Borra la matriz. Supongo que eso es lo que querías ...

+0

No, no lo es, te perdiste el punto. La pregunta es sobre la indirección. –