Pasa por una serie de cuerdas en Bash?

Quiero escribir un script que recorra 15 cadenas (posiblemente ¿matriz?) ¿Es posible?

Algo como:

for databaseName in listOfNames then # Do something end 

Puedes usarlo así:

 ## declare an array variable declare -a arr=("element1" "element2" "element3") ## now loop through the above array for i in "${arr[@]}" do echo "$i" # or do whatever with individual element of the array done # You can access them using echo "${arr[0]}", "${arr[1]}" also 

También funciona para statement de matriz multilínea

 declare -a arr=("element1" "element2" "element3" "element4" ) 

Eso es posible, por supuesto.

 for databaseName in abcdef; do # do something like: echo $databaseName done 

Vea Bash Loops for, while y until para más detalles.

Ninguna de esas respuestas incluye un contador …

 #!/bin/bash ## declare an array variable declare -a array=("one" "two" "three") # get length of an array arraylength=${#array[@]} # use for loop to read all values and indexes for (( i=1; i<${arraylength}+1; i++ )); do echo $i " / " ${arraylength} " : " ${array[$i-1]} done 

Salida:

 1 / 3 : one 2 / 3 : two 3 / 3 : three 

En el mismo espíritu que la respuesta de 4ndrew:

 listOfNames="RA RB RC RD" # To allow for other whitespace in the string: # 1. add double quotes around the list variable, or # 2. see the IFS note (under 'Side Notes') for databaseName in "$listOfNames" # <-- Note: Added "" quotes. do echo "$databaseName" # (ie do action / processing of $databaseName here...) done # Outputs # RA # RB # RC # RD 

B. No hay espacio en blanco en los nombres:

 listOfNames="RA RB RC RD" for databaseName in $listOfNames # Note: No quotes do echo "$databaseName" # (ie do action / processing of $databaseName here...) done # Outputs # RA # RB # R # C # RD 

Notas

  1. En el segundo ejemplo, el uso de listOfNames="RA RB RC RD" tiene el mismo resultado.

Otras formas de traer datos incluyen:

  • stdin (listado a continuación),
  • variables ,
  • una matriz (la respuesta aceptada),
  • un archivo ...

Leer de stdin

 # line delimited (each databaseName is stored on a line) while read databaseName do echo "$databaseName" # ie do action / processing of $databaseName here... done # <<< or_another_input_method_here 
  1. el separador bash IFS "separador de campo a línea" [ 1 ] se puede especificar en el script para permitir otros espacios en blanco (es decir, IFS='\n' , o para MacOS IFS='\r' )
  2. Me gusta la respuesta aceptada también :). He incluido estos fragmentos como otras formas útiles que también responden a la pregunta.
  3. Incluir #!/bin/bash en la parte superior del archivo de script indica el entorno de ejecución.
  4. Me llevó meses descubrir cómo codificar esto simplemente 🙂

Otras fonts ( while read loop )

Puede usar la syntax de ${arrayName[@]}

 #!/bin/bash # declare an array called files, that contains 3 values files=( "/etc/passwd" "/etc/group" "/etc/hosts" ) for i in "${files[@]}" do echo "$i" done 

 for Item in Item1 Item2 Item3 Item4 ; do echo $Item done 

Salida:

 Item1 Item2 Item3 Item4 

Sobre múltiples líneas

 for Item in Item1 \ Item2 \ Item3 \ Item4 do echo $Item done 

Salida:

 Item1 Item2 Item3 Item4 

Variable de lista simple

 List=( Item1 Item2 Item3 ) 

o

 List=( Item1 Item2 Item3 ) 

Mostrar la variable de la lista:

 echo ${List[*]} 

Fuera puesto:

 Item1 Item2 Item3 

Bucle a través de la lista:

 for Item in ${List[*]} do echo $Item done 

Fuera puesto:

 Item1 Item2 Item3 

Crea una función para ir a través de una lista:

 Loop(){ for item in ${*} ; do echo ${item} done } Loop ${List[*]} 

Para preservar espacios; entradas de lista de cotización simple o doble y expansiones de lista de cotización doble:

 List=(' Item 1 ' ' Item 2' ' Item 3' ) for item in "${List[@]}"; do echo "$item" done 

Salida:

  Item 1 Item 2 Item 3 

Usar la palabra clave declare (comando) para crear la lista, que técnicamente se llama una matriz:

 declare -a List=( "element 1" "element 2" "element 3" ) for entry in "${List[@]}" do echo "$entry" done 

Fuera puesto:

 element 1 element 2 element 3 

Creando una matriz asociativa. Un diccionario :

 declare -A continent continent[Vietnam]=Asia continent[France]=Europe continent[Argentina]=America for item in "${!continent[@]}"; do printf "$item is in ${continent[$item]} \n" done 

Salida:

  Argentina is in America Vietnam is in Asia France is in Europe 

Variables CVS o archivos en una lista .
Cambiar el separador de campo interno de un espacio, a lo que quieras.
En el siguiente ejemplo, se cambia a una coma

 List="Item 1,Item 2,Item 3" Backup_of_internal_field_separator=$IFS IFS=, for item in $List; do echo $item done IFS=$Backup_of_internal_field_separator 

Salida:

 Item 1 Item 2 Item 3 

Si es necesario numerarlos:

 ` 

esto se llama tic back. Pon el comando dentro de las marcas de retroceso.

 `commend` 

Está al lado del número uno en su teclado y encima de la tecla de tabulación. En un teclado estándar de inglés americano.

 List=() Start_count=0 Step_count=0.1 Stop_count=1 for Item in `seq $Start_count $Step_count $Stop_count` do List+=(Item_$Item) done for Item in ${List[*]} do echo $Item done 

Fuera de juego es:

 Item_0.0 Item_0.1 Item_0.2 Item_0.3 Item_0.4 Item_0.5 Item_0.6 Item_0.7 Item_0.8 Item_0.9 Item_1.0 

Familiarizarse con el comportamiento de los golpes:

Crea una lista en un archivo

 cat < List_entries.txt Item1 Item 2 'Item 3' "Item 4" Item 7 : * "Item 6 : * " "Item 6 : *" Item 8 : $PWD 'Item 8 : $PWD' "Item 9 : $PWD" EOF 

Lea el archivo de la lista en una lista y visualice

 List=$(cat List_entries.txt) echo $List echo '$List' echo "$List" echo ${List[*]} echo '${List[*]}' echo "${List[*]}" echo ${List[@]} echo '${List[@]}' echo "${List[@]}" 

Manual de referencia de la línea de comandos de BASH: significado especial de ciertos caracteres o palabras para el caparazón.

Esto también es fácil de leer:

 FilePath=( "/tmp/path1/" #FilePath[0] "/tmp/path2/" #FilePath[1] ) #Loop for Path in "${FilePath[@]}" do echo "$Path" done 

La matriz de statement no funciona para el shell Korn. Use el siguiente ejemplo para el shell Korn:

 promote_sla_chk_lst="cdi xlob" set -A promote_arry $promote_sla_chk_lst for i in ${promote_arry[*]}; do echo $i done 

Matriz implícita para secuencia de comandos o funciones:

Además de la respuesta correcta de anubhava : Si la syntax básica para el ciclo es:

 for var in "${arr[@]}" ;do ...$var... ;done 

hay un caso especial en bash :

Cuando se ejecuta un script o una función, los argumentos que se pasan en las líneas de comando se asignarán a la variable $@ array, se puede acceder por $1 , $2 , $3 , y así sucesivamente.

Esto puede ser poblado (para prueba) por

 set -- arg1 arg2 arg3 ... 

Un bucle sobre esta matriz podría escribirse simplemente:

 for item ;do echo "This is item: $item." done 

Tenga en cuenta que el trabajo reservado no está presente y tampoco el nombre de la matriz.

Muestra:

 set -- arg1 arg2 arg3 ... for item ;do echo "This is item: $item." done This is item: arg1. This is item: arg2. This is item: arg3. This is item: .... 

Tenga en cuenta que esto es lo mismo que

 for item in "$@";do echo "This is item: $item." done 

Luego en una secuencia de comandos :

 #!/bin/bash for item ;do printf "Doing something with '%s'.\n" "$item" done 

Guarde esto en un script myscript.sh , chmod +x myscript.sh , luego

 ./myscript.sh arg1 arg2 arg3 ... Doing something with 'arg1'. Doing something with 'arg2'. Doing something with 'arg3'. Doing something with '...'. 

Lo mismo en una función :

 myfunc() { for item;do cat <<<"Working about '$item'."; done ; } 

Entonces

 myfunc item1 tiem2 time3 Working about 'item1'. Working about 'tiem2'. Working about 'time3'. 
 listOfNames="db_one db_two db_three" for databaseName in $listOfNames do echo $databaseName done 

o solo

 for databaseName in db_one db_two db_three do echo $databaseName done 

Si está usando shell Korn, hay ” set -A databaseName “, de lo contrario hay ” declare -a databaseName

Para escribir un script que funcione en todos los shells,

  set -A databaseName=("db1" "db2" ....) || declare -a databaseName=("db1" "db2" ....) # now loop for dbname in "${arr[@]}" do echo "$dbname" # or whatever done 

Debería ser trabajo en todas las conchas.

Esto es similar a la respuesta del usuario2533809, pero cada archivo se ejecutará como un comando separado.

 #!/bin/bash names="RA RB RC RD" while read -r line; do echo line: "$line" done <<< "$names" 

Posible primera línea de cada secuencia de comandos / sesión de Bash:

 say() { for line in "${@}" ; do printf "%s\n" "${line}" ; done ; } 

Use por ejemplo:

 $ aa=( 7 -4 -e ) ; say "${aa[@]}" 7 -4 -e 

Puede considerar: el echo interpreta -e como una opción aquí

Sola línea de bucle,

  declare -a listOfNames=('db_a' 'db_b' 'db_c') for databaseName in ${listOfNames[@]}; do echo $databaseName; done; 

obtendrás una salida como esta,

 db_a db_b db_c 

Sorprendió que nadie haya publicado esto todavía; si necesita los índices de los elementos mientras recorre el conjunto, puede hacer esto:

 arr=(foo bar baz) for i in ${!arr[@]} do echo $i "${arr[i]}" done 

Salida:

 0 foo 1 bar 2 baz 

Encuentro esto mucho más elegante que el estilo for-loop “tradicional” ( for (( i=0; i<${#arr[@]}; i++ )) ).

( ${!arr[@]} y $i no necesito que me lo citen porque son solo números; algunos sugieren citarlos de todos modos, pero eso es solo preferencia personal).

Prueba esto. Está trabajando y probado.

 for k in "${array[@]}" do echo $k done # For accessing with the echo command: echo ${array[0]}, ${array[1]} 

Manera simple :

 arr=("sharlock" "bomkesh" "feluda" ) ##declare array len=${#arr[*]} # it returns the array length #iterate with while loop i=0 while [ $i -lt $len ] do echo ${arr[$i]} i=$((i+1)) done #iterate with for loop for i in $arr do echo $i done #iterate with splice echo ${arr[@]:0:3} 

Repaso una serie de mis proyectos para obtener una actualización de git pull :

 #!/bin/sh projects=" web ios android " for project in $projects do cd $HOME/develop/$project && git pull end