bash loop a través de la lista de cadenas


13

¿Es posible formatear esta muestra?

for i in string1 string2 stringN
do
 echo $i
done

a algo similar a esto:

for i in 
string1
string2
stringN
do
 echo $i
done

EDITAR: Perdón por la confusión, no me di cuenta de que había diferentes métodos para ejecutar el script: sh <scriptname>versus bash <scriptname>y también esta cosa que no puedo nombrar en este momento, #!/bin/shy #!/bin/bash:)


¿Cuál es el problema que estás tratando de resolver?
jesse_b

¿Intentaste lo que estás pidiendo para ver si funcionaría?
DopeGhoti

@Jesse_b legibilidad y manejabilidad de un montón de cadenas

@DopeGhoti sí, lo hice

@waayee: en ese caso, una matriz es tu mejor apuesta. Ver la respuesta de Glenn Jackman.
jesse_b

Respuestas:


32

El uso de matrices en bash puede ayudar a la legibilidad: esta sintaxis de matriz permite espacios en blanco arbitrarios entre palabras.

strings=(
    string1
    string2
    "string with spaces"
    stringN
)
for i in "${strings[@]}"; do
    echo "$i"
done

1
Esto parece muy elegante, pero desafortunadamente da error: Error de sintaxis: "(" inesperado

1
@waayee, entonces no lo estás ejecutando en Bash. Recuerde que shno es necesariamente Bash, y especialmente no está en Debian y Ubuntu.
ilkkachu

1
@ilkkachu Creo que lo entiendo ahora - debe ejecutar "bash <scriptname>" no "sh <scriptname>" :)

@waayee, o coloque una línea hashbang / shebang adecuada y ejecútela como un ejecutable. Lectura requerida: ¿Shebang determina el shell que ejecuta el script?
ilkkachu

1
@rrrrr, sus preguntas probablemente sean respondidas aquí: stackoverflow.com/q/12314451/7552
glenn jackman

4

Puedes escapar del salto de línea con una barra invertida:

$ for i in \
> hello \
> world
> do
> echo $i
> done
hello
world
$

2

Puede escapar de las nuevas líneas antes / después de cada elemento que recorre:

for i in \
    string1 \
    string2 \
    stringN
do
   printf '%s\n' "$i"
done

O, para este simple ejemplo:

printf '%s\n' string1 string2 stringN

que tiene el mismo resultado.

Relacionado:

Variación usando una bashmatriz:

strings=(
    string1
    string2
    stringN
)

printf '%s\n' "${strings[@]}"

1

Si cambiar a zshes una opción:

for string (
  string1
  'other string'
  etc..
) printf '%s\n' "$string"

0

Puede usar el loopcomando, disponible aquí , así:

$ loop "echo $ITEM" --for string1,string2,string3

o, si tiene una lista como archivo:

$ cat file_list.txt | loop "echo $ITEM"

0
list='a b c d'
for element in $list;do 
    echo "$element"
done

Te faltan puntos y comas!
41754

Tenga en cuenta que esto funcionaría siempre que cada cadena sea una palabra separada. Tan pronto como tenga espacios en sus cadenas, los espacios separarían la cadena en varias palabras. Además, si la $listcadena contiene caracteres globales de nombre de archivo ( list='* * * *'), el shell podría reemplazarlos por nombres de archivo coincidentes.
Kusalananda

0

Lo mismo, menos texto:

array=(
        string{1..7}
)

for i in "${array[@]}"; do
    echo "$i"
done

string1etc. no son los valores literales que se mostrarán, son marcadores de posición, por lo que este enfoque no funciona.
Stephen Kitt

Si es así, ¿por qué molestarse array ( … )? solo hazlo for i in string{1..7}; do echo "$i"; done; parprintf '%s\n' string{1..7}
αғsнιη
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.