arrays - script - Recorrer una serie de cadenas en Bash?
linux shell define array (19)
Array implícito para script o funciones:
Además de la respuesta correcta de anubhava : si la sintaxis básica para bucle es:
for item ;do
echo "This is item: $item."
done
Hay un caso especial en bash :
Al ejecutar un script o una función, los argumentos pasados en las líneas de comando se asignarán a la variable $@
array, puede acceder a $1
, $2
, $3
, etc.
Esto puede ser poblado (para prueba) por
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: ....
Un bucle sobre esta matriz podría escribirse simplemente:
for item in "$@";do
echo "This is item: $item."
done
Tenga en cuenta que el trabajo reservado no está presente y no hay nombre de matriz también.
Muestra:
#!/bin/bash
for item ;do
printf "Doing something with ''%s''./n" "$item"
done
Tenga en cuenta que esto es lo mismo que
./myscript.sh arg1 arg2 arg3 ...
Doing something with ''arg1''.
Doing something with ''arg2''.
Doing something with ''arg3''.
Doing something with ''...''.
Luego en un guión :
myfunc() { for item;do cat <<<"Working about ''$item''."; done ; }
Guarde esto en un script myscript.sh
, chmod +x myscript.sh
, luego
myfunc item1 tiem2 time3
Working about ''item1''.
Working about ''tiem2''.
Working about ''time3''.
Lo mismo en una función :
arr=(foo bar baz)
for i in ${!arr[@]}
do
echo $i "${arr[i]}"
done
Entonces
0 foo
1 bar
2 baz
Quiero escribir un script que recorra 15 cadenas (¿posiblemente un arreglo)?
Algo como:
for databaseName in listOfNames
then
# Do something
end
Bucle de una sola línea,
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
En el mismo espíritu que la respuesta de 4ndrew:
listOfNames="RA
RB
R C
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" # (i.e. do action / processing of $databaseName here...)
done
# Outputs
# RA
# RB
# R C
# RD
B. No hay espacios en blanco en los nombres:
listOfNames="RA
RB
R C
RD"
for databaseName in $listOfNames # Note: No quotes
do
echo "$databaseName" # (i.e. do action / processing of $databaseName here...)
done
# Outputs
# RA
# RB
# R
# C
# RD
Notas
- En el segundo ejemplo, el uso de
listOfNames="RA RB RC RD"
tiene el mismo resultado.
Otras formas de traer datos incluyen:
- stdin (listado abajo),
- 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" # i.e. do action / processing of $databaseName here...
done # <<< or_another_input_method_here
- el delimitador de campo "separador de campo a línea" [ 1 ] de IFS se puede especificar en el script para permitir otros espacios en blanco (es decir,
IFS=''/n''
, o para MacOSIFS=''/r''
) - También me gusta la respuesta aceptada :) - He incluido estos fragmentos de código como otras formas útiles que también responden a la pregunta.
- Incluir
#!/bin/bash
en la parte superior del archivo de script indica el entorno de ejecución. - Me tomó meses descubrir cómo codificar esto simplemente :)
Otras fuentes ( mientras se lee el bucle )
Eso es posible, por supuesto.
for databaseName in a b c d e f; do
# do something like: echo $databaseName
done
Vea Bash Loops para, mientras y hasta para más detalles.
Esta es la solución más simple, asumiendo que no hay espacios en los nombres:
listOfNames="db_one db_two db_three"
for databaseName in $listOfNames
do
echo $databaseName
done
Esto es similar a la respuesta del usuario 2533809, pero cada archivo se ejecutará como un comando separado.
#!/bin/bash
names="RA
RB
R C
RD"
while read -r line; do
echo line: "$line"
done <<< "$names"
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 declare no funciona para el shell Korn. Utilice el siguiente ejemplo para el shell Korn:
set -- arg1 arg2 arg3 ...
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}
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
Posible primera línea de cada script / sesión de Bash:
say() { for line in "${@}" ; do printf "%s/n" "${line}" ; done ; }
Utilizar por ejemplo:
$ aa=( 7 -4 -e ) ; say "${aa[@]}"
7
-4
-e
Puede considerar: echo
interpreta -e
como opción aquí
Prueba esto. Está funcionando y probado.
for k in "${array[@]}"
do
echo $k
done
# For accessing with the echo command: echo ${array[0]}, ${array[1]}
Puede usar la sintaxis de ${arrayName[@]}
List=$(cat List_entries.txt)
echo $List
echo ''$List''
echo "$List"
echo ${List[*]}
echo ''${List[*]}''
echo "${List[*]}"
echo ${List[@]}
echo ''${List[@]}''
echo "${List[@]}"
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 la declaración de matriz multilínea
declare -a arr=("element1"
"element2" "element3"
"element4"
)
Recorro una serie de mis proyectos para una actualización de git pull
:
#!/bin/sh
projects="
web
ios
android
"
for project in $projects do
cd $HOME/develop/$project && git pull
end
Si está utilizando el shell Korn, hay " set -A databaseName ", de lo contrario hay " declare -a databaseName "
Para escribir un script trabajando 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
Debe ser trabajo en todas las conchas.
Sorprendido de que nadie haya publicado esto todavía, si necesita los índices de los elementos mientras recorre la matriz, puede hacer esto:
promote_sla_chk_lst="cdi xlob"
set -A promote_arry $promote_sla_chk_lst
for i in ${promote_arry[*]};
do
echo $i
done
Salida:
for var in "${arr[@]}" ;do ...$var... ;done
Me parece mucho más elegante que el estilo "tradicional" de bucle for (( i=0; i<${#arr[@]}; i++ ))
).
( ${!arr[@]}
y $i
no necesito ser citado porque son solo números; algunos sugerirían citarlos de todos modos, pero eso es solo una preferencia personal).
Sí
#!/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
Salida:
for Item in Item1 Item2 Item3 Item4 ;
do
echo $Item
done
Sobre lineas multiples
Item1
Item2
Item3
Item4
Salida:
for Item in Item1 /
Item2 /
Item3 /
Item4
do
echo $Item
done
Variable de lista simple
Item1
Item2
Item3
Item4
o
List=( Item1 Item2 Item3 )
Mostrar la variable de lista:
List=(
Item1
Item2
Item3
)
Fuera puesto
echo ${List[*]}
Recorre la lista:
Item1 Item2 Item3
Fuera puesto
for Item in ${List[*]}
do
echo $Item
done
Crear una función para ir a través de una lista:
Item1
Item2
Item3
Para preservar espacios; Entradas de listas de comillas simples o dobles y ampliaciones de listas de comillas dobles:
Loop(){
for item in ${*} ;
do
echo ${item}
done
}
Loop ${List[*]}
Salida:
List=('' Item 1 ''
'' Item 2''
'' Item 3''
)
for item in "${List[@]}";
do
echo "$item"
done
Usando la palabra clave declare (comando) para crear la lista, que técnicamente se llama una matriz:
Item 1
Item 2
Item 3
Fuera puesto
declare -a List=(
"element 1"
"element 2"
"element 3"
)
for entry in "${List[@]}"
do
echo "$entry"
done
Creando una matriz asociativa. Un diccionario :
element 1
element 2
element 3
Salida:
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
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.
Argentina is in America
Vietnam is in Asia
France is in Europe
Salida:
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
Si es necesario enumerarlos:
Item 1
Item 2
Item 3
Esto se llama una garrapata hacia atrás. Ponga el comando dentro de las garrapatas.
`
Está al lado del número uno en su teclado y / o encima de la tecla de tabulación. En un teclado de idioma inglés americano estándar.
`commend`
Fuera de puesto es:
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
Familiarizarse más con el comportamiento de los golpes:
Crear una lista en un archivo
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
Lea el archivo de lista en una lista y muestre
cat <<EOF> 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
for databaseName in db_one db_two db_three
do
echo $databaseName
done
o solo
listofNames = "A B C D"
for databaseName in $listOfNames; do
echo $databaseName
done