Diskussion
使用する seq
ist in Ordnung, wie Jiaaro vorgeschlagen hat. Pax Diablo schlug eine Bash-Schleife vor, um den Aufruf eines Unterprozesses zu vermeiden, mit dem zusätzlichen Vorteil, dass sie speicherfreundlicher ist, wenn $END zu groß ist. Zathrus entdeckte einen typischen Fehler in der Schleifenimplementierung und wies auch darauf hin, dass, da i
eine Textvariable ist, werden kontinuierliche Konvertierungen von und zu Zahlen mit einer entsprechenden Verlangsamung durchgeführt.
Ganzzahlarithmetik
Dies ist eine verbesserte Version der Bash-Schleife:
typeset -i i END
let END=5 i=1
while ((i<=END)); do
echo $i
…
let i++
done
Wenn das einzige, was wir wollen, die echo
dann könnten wir schreiben echo $((i++))
.
Ephemeride hat mich etwas gelehrt: Bash erlaubt for ((expr;expr;expr))
Konstrukte. Da ich noch nie die gesamte Manualseite der Bash gelesen habe (wie ich es bei der Korn-Shell getan habe ( ksh
) man page, und das ist schon lange her), habe ich das übersehen.
Also,
typeset -i i END # Let's be explicit
for ((i=1;i<=END;++i)); do echo $i; done
scheint der speichereffizienteste Weg zu sein (es wird nicht nötig sein, Speicher zuzuweisen, um die seq
Ausgabe, was ein Problem sein könnte, wenn END sehr groß ist), wenn auch wahrscheinlich nicht die "schnellste".
die Ausgangsfrage
eschercycle stellte fest, dass die { a .. b } Die Bash-Notation funktioniert nur mit Literalen; true, entsprechend dem Bash-Handbuch. Man kann dieses Hindernis mit einem einzigen (internen) fork()
ohne einen exec()
(wie bei dem Aufruf von seq
(ein weiteres Image, das einen Fork+exec erfordert):
for i in $(eval echo "{1..$END}"); do
Beide eval
y echo
sind Bash-Builtins, aber ein fork()
ist für die Befehlssubstitution erforderlich (die $(…)
Konstrukt).
41 Stimmen
Hallo zusammen, die Informationen und Tipps, die ich hier gelesen habe, sind alle sehr hilfreich. Ich denke, es ist am besten, die Verwendung von seq zu vermeiden. Der Grund dafür ist, dass einige Skripte portabel sein müssen und auf einer Vielzahl von Unix-Systemen laufen müssen, auf denen einige Befehle möglicherweise nicht vorhanden sind. Nur um ein Beispiel zu nennen: seq ist auf FreeBSD-Systemen standardmäßig nicht vorhanden.
2 Stimmen
Verwandte Themen: bash for-Schleife: ein Bereich von Zahlen y unix.stackexchange.com - Ist es in der Bash möglich, eine Integer-Variable in der Schleifensteuerung einer for-Schleife zu verwenden?
12 Stimmen
Ich weiß nicht mehr, seit welcher Version der Bash genau, aber dieser Befehl unterstützt auch abschließende Nullen. Was manchmal wirklich hilfreich ist. Befehl
for i in {01..10}; do echo $i; done
würde Zahlen ergeben wie01, 02, 03, ..., 10
.4 Stimmen
Für diejenigen, die wie ich nur über den Bereich der Indizes einer Array wäre die Bash-Methode:
myarray=('a' 'b' 'c'); for i in ${!myarray[@]}; do echo $i; done
(beachten Sie das Ausrufezeichen). Sie ist spezifischer als die ursprüngliche Frage, könnte aber hilfreich sein. Siehe Bash-Parameter-Erweiterungen1 Stimmen
Die Klammererweiterung wird auch für Ausdrücke verwendet wie
{jpg,png,gif}
was hier nicht direkt angesprochen wird, obwohl die Antwort identisch sein wird. Siehe Klammererweiterung mit Variable? [Duplikat] die als Duplikat dieses Dokuments gekennzeichnet ist.0 Stimmen
Freebsd scheint zu haben
seq
jetzt "in diesen Tagen" FWIW...0 Stimmen
Intenté
for i in {1..${END}}; do echo ${i}; done
. Dies funktioniert in der Terminal-Befehlszeile, aber nicht in einem SHELL-Skript, was mich verwirrt.1 Stimmen
@PhoenixMu, Sie können das Shell-Skript mit bash yourscript.sh statt mit sh yourscript.sh ausführen
0 Stimmen
@XinNiu Stimmt;