cómo cambiar el valor de la matriz en bash

8

queremos construir 6 carpetas de puntos de montaje como ejemplo

/data/sdb
/data/sdc
/data/sdd
/data/sde
/data/sdf
/data/sdg

así que escribimos este simple script bash usando array

folder_mount_point_list="sdb sdc sdd sde sdf sdg"

folderArray=( $folder_mount_point_list )

counter=0
for i in disk1 disk2 disk3 disk4 disk4 disk5 disk6
do
folder_name=${folderArray[counter]}
mkdir /data/$folder_name
let counter=$counter+1
done

ahora queremos cambiar el código sin contador y dejar = $ contador = contador + 1

¿Es posible cambiar cada ciclo de la matriz para obtener el siguiente valor de la matriz?

como algo así

${folderArray[++]}
yael
fuente
1
¿ for i in disk1 disk2 disk3 disk4 disk4 disk5 disk6para qué, ya que no se usa dentro del cuerpo del bucle?
RomanPerekhrest
1
... y cuál es el punto de usar un contador? ¿Por qué no simplemente corres for i in "your_list_goes_here"; do mkdir /data/"$i"; done?
don_crissti

Respuestas:

10

Un comentario general. No tiene sentido definir una matriz como esta:

folder_mount_point_list="sdb sdc sdd sde sdf sdg"
folderArray=( $folder_mount_point_list )

En su lugar, haría esto:

folderArray=(sdb sdc sdd sde sdf sdg)

Ahora a su pregunta:

set -- sdb sdc sdd sde sdf sdg
for folder_name; do
    mkdir "/data/$folder_name"
done

o

set -- sdb sdc sdd sde sdf sdg
while [ $# -gt 0 ]; do
    mkdir "/data/$1"
    shift
done
Hauke ​​Laging
fuente
podemos hacer el conjunto de variables como set - $ list_of_folders (mientras list_of_folders = "SDB SDC SDD sde"
Yael
@yael Sí, puede usar, set -- $list_of_folderspero de nuevo: las variables de cadena no son el camino a seguir:set -- "${folders[@]}"
Hauke ​​Laging
1
¿Por qué estás usando set -- ....? ese truco solo es necesario en shells que no admiten matrices; no es necesario en un shell que sí admite matrices. for folder_name in "${folderArray[@]}"; do ... ; donees todo lo que se necesita
cas
solo una pregunta, ¿hay alguna opción para hacer algo como - $ {folderArray [++]}
yael el
@cas eso es lo que tengo en mi respuesta. Tampoco entiendo este setenfoque.
PesaEl
14

Para responder la pregunta en el título, puede "desplazar" una matriz con la notación de subcadena / submatriz. ( shiftfunciona solo con los parámetros posicionales).

$ a=(a b c d e)
$ a=("${a[@]:1}")
$ echo "${a[@]}"
b c d e

Del mismo modo, para 'hacer estallar' el último elemento de la matriz: a=("${a[@]:0:${#a[@]} - 1}" )ounset "a[${#a[@]}-1]"

Entonces, si quisieras, podrías hacer esto:

a=(foo bar doo)
b=(123 456 789)
while [ "${#a[@]}" -gt 0 ] ; do
    echo "$a $b"
    a=("${a[@]:1}")
    b=("${b[@]:1}")
done

Pero destruye las matrices, por lo que simplemente indexar como de costumbre podría ser mejor. O tal vez use una matriz asociativa en su lugar:

declare -A arr=([foo]=123 [bar]=456 [doo]=789)
ilkkachu
fuente
4

Simplemente puede recorrer todos los valores, sin necesidad de cambios:

folderArray=(sdb sdc sdd sde sdf sdg)

for folder in "${folderArray[@]}"; do
    mkdir "/data/$folder"
done
PesaThe
fuente
3

No necesita ningún bucle para eso:

folderArray=(sdb sdc sdd sde sdf sdg)
IFS=,
eval mkdir /data/{"${folderArray[*]}"}

El truco es que si una matriz se cita con subíndice *( "${array[*]}"), se expande a una sola palabra con el valor de cada elemento de matriz separado por el primer carácter de la IFSvariable. Después de eso, usamos un mecanismo de expansión de llaves para unir /data/a cada miembro de la matriz y evalevaluar todo.

jimmij
fuente
¿Por qué tan complicado? cd /data ; mkdir "${folderArray[@]}"He hecho lo mismo antes, pero no lo haría en un caso como este. Pero +1 para el enfoque avanzado.
Hauke ​​Laging
@HaukeLaging Sí, eso sería más simple en caso de mkdircomando. E incluso la matriz no es necesaria, tal cd /data; mkdir abc defcomo lo haría una persona normal. Pero no podría ser tan simple para otras tareas, por lo que es bueno saber cómo adjuntar rápidamente una cadena a cada elemento de la matriz sin un bucle.
jimmij
solo una pregunta, ¿hay alguna opción para hacer algo como - $ {folderArray [++]}
yael el
1
@yael Puedes hacer algo como echo "${folderArray[((counter++))]}"si realmente te gusta este enfoque. Las cosas en el interior (())se evalúan como matemáticas (observe la falta de $delante counter).
jimmij
1
y cuando comienzas a escribir código shell así, te das cuenta de que dedicar un poco de tiempo a aprender perl o python sería una buena idea. es decir, sólo porque usted puede hacer algo con bash, no significa que usted debe .
cas