Em um script de shell bash, escrevendo um loop for que itera sobre valores de string

21

No bash, eu sei que é possível escrever um loop for no qual alguma variável de controle de loop i itera sobre inteiros especificados. Por exemplo, posso escrever um script de shell bash que imprime os inteiros entre 1 e 10:

#!/bin/bash

for i in {1..10}
do
 echo $i
done

É possível, em vez disso, iterar sobre uma variável de controle de loop que é uma string, se eu fornecer uma lista de strings? Por exemplo, suponha que eu tenha uma string fname que represente um nome de arquivo. Eu quero chamar um conjunto de comandos para cada nome de arquivo. Por exemplo, talvez eu queira imprimir o conteúdo de fname usando um comando como este:

#!/bin/bash

for fname in {"a.txt", "b.txt", "c.txt"}
do
 echo $fname
done

Em outras palavras, na primeira iteração, fname deve ter o valor fname="a.txt" , enquanto na segunda iteração, fname deve ter o valor fname="b.txt" e assim por diante. Infelizmente, parece que a sintaxe acima não está correta. Eu gostaria de obter a saída:

a.txt

b.txt

c.txt

mas quando tento o código acima, obtenho esta saída:

{a.txt,

b.txt,

c.txt}

Por favor, você pode me ajudar a determinar a sintaxe correta, para que eu possa alterar iterativamente o valor / conteúdo da variável fname ? Obrigado pelo seu tempo.

    
por Andrew 08.09.2012 / 17:50

3 respostas

35

A sintaxe correta é a seguinte:

#!/bin/bash

for fname in a.txt b.txt c.txt
do
  echo $fname
done
    
por 08.09.2012 / 18:48
1

Parece que você deveria apenas fazer ...

printf %s.txt\n a b c
    
por 13.02.2015 / 08:35
0

Como observado por user13742 no comentários , podemos fazer uso de matrizes em bash e ksh :

#!/usr/bin/env bash

files_list=( "a.txt" "b.txt" "c and space.txt" )

for i in "${files_list[@]}"
do
    echo "$i"
    # do something else here,maybe
done

E funciona assim:

$ ./iterate_files_array.sh                                                      
a.txt
b.txt
c and space.txt

No entanto, alguns shells como dash ( /bin/sh no Ubuntu) não suportam matrizes. Nesse caso, poderíamos recorrer ao uso da estrutura here-document: <<

#!/bin/sh

while IFS= read -r line
do
    echo "$line"
done << EOL
one.txt
two.txt
with space.txt
EOL
    
por 12.11.2017 / 23:34