loop bash através da lista de strings


13

É possível formatar este exemplo:

for i in string1 string2 stringN
do
 echo $i
done

para algo semelhante a este:

for i in 
string1
string2
stringN
do
 echo $i
done

EDIT: Desculpe por confusão, não percebi que havia diferentes métodos de execução de script - sh <scriptname>versus bash <scriptname>e também essa coisa que eu não posso nomear agora - #!/bin/she #!/bin/bash:)


Qual é o problema que você está tentando resolver?
21818 jesse_b #

Você tentou o que está pedindo para ver se funcionaria?
DopeGhoti

@Jesse_b legibilidade e capacidade de gerenciamento de um monte de strings

@DopeGhoti sim, eu fiz

@waayee: Nesse caso, uma matriz é sua melhor aposta. Veja a resposta de Glenn Jackman.
jesse_b

Respostas:


32

O uso de matrizes no bash pode ajudar na legibilidade: essa sintaxe da matriz permite um espaço em branco arbitrário entre as palavras.

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

1
Isso parece mais elegante, mas infelizmente dá o erro: Erro de sintaxe: "(" inesperado

1
@waayee, então você não está executando o Bash. Lembre-se que shnão é necessariamente o Bash, e especialmente não está no Debian e no Ubuntu.
ilkkachu

1
@ilkkachu Acho que obtê-lo agora - deve executar "bash <scriptname>" não "sh <scriptname>" :)

@waayee, ou coloque uma linha apropriada de hashbang / shebang e execute-a como um executável. Leitura obrigatória: O shebang determina o shell que executa o script?
ilkkachu

1
@rrrrr, suas perguntas são provavelmente respondida aqui: stackoverflow.com/q/12314451/7552
glenn jackman

4

Você pode escapar da quebra de linha com uma barra invertida:

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

2

Você pode escapar das novas linhas antes / depois de cada item em que faz o loop:

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

Ou, para este exemplo simples:

printf '%s\n' string1 string2 stringN

que tem o mesmo resultado.

Relacionado:

Variação usando uma bashmatriz:

strings=(
    string1
    string2
    stringN
)

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

1

Se mudar para zshé uma opção:

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

0

Você pode usar o loopcomando, disponível aqui , da seguinte forma:

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

ou, se você tiver uma lista como um arquivo:

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

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

Faltam ponto e vírgula!
41754 23/07/19

Observe que isso funcionaria desde que cada sequência seja uma palavra separada. Assim que você tiver espaços em suas cadeias, os espaços dividirão a cadeia em várias palavras. Além disso, se a $liststring contiver caracteres inativos do nome do arquivo ( list='* * * *'), o shell poderá substituí-los por nomes de arquivos correspondentes.
Kusalananda

0

Mesma coisa, menos texto:

array=(
        string{1..7}
)

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

string1etc. não são os valores literais a serem exibidos, são espaços reservados, portanto, essa abordagem não funciona.
Stephen Kitt

Se sim, por que se preocupar array ( … )? apenas faça for i in string{1..7}; do echo "$i"; done; evenprintf '%s\n' string{1..7}
αғsнιη 28/01
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.