boucle bash à travers la liste des chaînes

13

Est-il possible de formater cet exemple:

for i in string1 string2 stringN
do
 echo $i
done

à quelque chose de similaire à ceci:

for i in 
string1
string2
stringN
do
 echo $i
done

EDIT: Désolé pour la confusion, je ne savais pas qu'il y avait différentes méthodes d'exécution de script - sh <scriptname>versus bash <scriptname>et aussi cette chose que je ne peux pas nommer pour le moment - #!/bin/shet #!/bin/bash:)


la source
Quel est le problème que vous essayez de résoudre?
jesse_b
Avez-vous essayé ce que vous demandez pour voir si cela fonctionnerait?
DopeGhoti
@Jesse_b lisibilité et maniabilité d'un tas de chaînes
@DopeGhoti oui je l'ai fait
@waayee: Dans ce cas, un tableau est votre meilleur choix. Voir la réponse de Glenn Jackman.
jesse_b

Réponses:

32

L'utilisation de tableaux dans bash peut faciliter la lisibilité: cette syntaxe de tableau permet des espaces arbitraires entre les mots.

strings=(
    string1
    string2
    "string with spaces"
    stringN
)
for i in "${strings[@]}"; do
    echo "$i"
done
glenn jackman
la source
1
Cela semble plus élégant, mais donne malheureusement une erreur: Erreur de syntaxe: "(" inattendu
1
@waayee, alors vous ne l'exécutez pas dans Bash. N'oubliez pas que ce shn'est pas nécessairement Bash, et surtout pas sur Debian et Ubuntu.
ilkkachu
1
@ilkkachu Je pense que je comprends maintenant - doit exécuter "bash <scriptname>" et non "sh <scriptname>" :)
@waayee, ou mettez une ligne hashbang / shebang appropriée et exécutez-la comme un exécutable. Lecture obligatoire: le shebang détermine-t-il le shell qui exécute le script?
ilkkachu
1
@rrrrr, vos questions sont probablement répondues ici: stackoverflow.com/q/12314451/7552
glenn jackman
4

Vous pouvez échapper au saut de ligne avec une barre oblique inverse:

$ for i in \
> hello \
> world
> do
> echo $i
> done
hello
world
$
Andy Dalton
la source
2

Vous pouvez échapper aux sauts de ligne avant / après chaque élément que vous parcourez:

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

Ou, pour cet exemple simple:

printf '%s\n' string1 string2 stringN

qui a le même résultat.

En relation:

Variation à l'aide d'un bashtableau:

strings=(
    string1
    string2
    stringN
)

printf '%s\n' "${strings[@]}"
Kusalananda
la source
1

Si le passage à zshest une option:

for string (
  string1
  'other string'
  etc..
) printf '%s\n' "$string"
Stéphane Chazelas
la source
0

Vous pouvez utiliser la loopcommande, disponible ici , comme ceci:

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

ou, si vous avez une liste sous forme de fichier:

$ cat file_list.txt | loop "echo $ITEM"
Rich Jones
la source
0
list='a b c d'
for element in $list;do 
    echo "$element"
done
client
la source
Il vous manque des points-virgules!
41754
Notez que cela fonctionnerait tant que chaque chaîne est un mot distinct. Dès que vous avez des espaces dans vos chaînes, les espaces séparent la chaîne en plusieurs mots. De plus, si la $listchaîne contient des caractères de list='* * * *'remplacement de nom de fichier ( ), le shell pourrait potentiellement les remplacer par des noms de fichiers correspondants.
Kusalananda
0

Même chose, moins de texte:

array=(
        string{1..7}
)

for i in "${array[@]}"; do
    echo "$i"
done
Cornelis van Ginkel
la source
string1etc. ne sont pas les valeurs littérales à afficher, ce sont des espaces réservés, donc cette approche ne fonctionne pas.
Stephen Kitt
si oui, pourquoi s'embêter array ( … )? fais juste for i in string{1..7}; do echo "$i"; done; pairprintf '%s\n' string{1..7}
αғsнιη