Bash-Schleife durch Liste der Zeichenfolgen

12

Ist es möglich, dieses Beispiel zu formatieren:

for i in string1 string2 stringN
do
 echo $i
done

zu etwas ähnlichem:

for i in 
string1
string2
stringN
do
 echo $i
done

EDIT: Entschuldigung für die Verwirrung, wusste nicht, dass es verschiedene Methoden zum Ausführen von Skripten gibt - sh <scriptname>versus bash <scriptname>und auch dieses Ding, das ich momentan nicht benennen kann - #!/bin/shund #!/bin/bash:)


quelle
Was ist das Problem, das Sie lösen möchten?
Jesse_b
Haben Sie versucht, was Sie fragen, um zu sehen, ob es funktionieren würde?
DopeGhoti
@ Jesse_b Lesbarkeit und Verwaltbarkeit von Strings
@DopeGhoti ja ich habe
@waayee: In diesem Fall ist ein Array die beste Wahl. Siehe Glenn Jackmans Antwort.
Jesse_b

Antworten:

31

Die Verwendung von Arrays in Bash kann die Lesbarkeit verbessern: Diese Array-Syntax ermöglicht beliebige Leerzeichen zwischen Wörtern.

strings=(
    string1
    string2
    "string with spaces"
    stringN
)
for i in "${strings[@]}"; do
    echo "$i"
done
Glenn Jackman
quelle
1
Dies scheint am elegantesten, gibt aber leider Fehler: Syntaxfehler: "(" unerwartet
1
@waayee, dann lässt du es nicht in Bash laufen. Denken Sie daran, dass dies shnicht unbedingt Bash ist und insbesondere nicht unter Debian und Ubuntu.
Ilkkachu
1
@ilkkachu Denke, ich verstehe es jetzt - muss "bash <Skriptname>" ausführen, nicht "sh <Skriptname>" :)
@waayee, oder setzen Sie eine richtige Hashbang / Shebang-Zeile und führen Sie sie wie eine ausführbare Datei aus. Erforderliche Lektüre: Bestimmt der Shebang die Shell, in der das Skript ausgeführt wird?
Ilkkachu
1
@rrrrr, Ihre Fragen werden wahrscheinlich hier beantwortet: stackoverflow.com/q/12314451/7552
Glenn Jackman
4

Sie können dem Zeilenumbruch mit einem Backslash entkommen:

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

Sie können die Zeilenumbrüche vor / nach jedem Element, über das Sie eine Schleife ausführen, umgehen:

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

Oder für dieses einfache Beispiel:

printf '%s\n' string1 string2 stringN

das hat das gleiche Ergebnis.

Verbunden:

Variation mit einem bashArray:

strings=(
    string1
    string2
    stringN
)

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

Wenn ein Wechsel zu möglich zshist:

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

Sie können den hierloop verfügbaren Befehl folgendermaßen verwenden :

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

oder, wenn Sie eine Liste als Datei haben:

$ cat file_list.txt | loop "echo $ITEM"
Rich Jones
quelle
0
list='a b c d'
for element in $list;do 
    echo "$element"
done
Gast
quelle
Ihnen fehlen Semikolons!
41754
Beachten Sie, dass dies funktionieren würde, solange jede Zeichenfolge ein separates Wort ist. Sobald Sie Leerzeichen in Ihren Zeichenfolgen haben, teilen die Leerzeichen die Zeichenfolge in mehrere Wörter auf. Wenn die $listZeichenfolge Dateinamen-Globbing-Zeichen ( list='* * * *') enthält, ersetzt die Shell diese möglicherweise durch übereinstimmende Dateinamen.
Kusalananda
0

Gleiches, weniger Text:

array=(
        string{1..7}
)

for i in "${array[@]}"; do
    echo "$i"
done
Cornelis van Ginkel
quelle
string1usw. sind nicht die anzuzeigenden Literalwerte, sondern Platzhalter, sodass dieser Ansatz nicht funktioniert.
Stephen Kitt
wenn ja, warum sich die Mühe machen array ( … )? mach es einfach for i in string{1..7}; do echo "$i"; done; geradeprintf '%s\n' string{1..7}
αғsнιη