Ich habe versucht, ein sehr einfaches Bash-Skript zu erstellen, um alle Vielfachen von fünf zwischen 375 und 3500 (375, 380, 385 ...) aufzulisten. Eine Sache, die ich versucht habe und die nicht funktioniert hat, ist:
for i in {375..3500}
do
echo $i
(($i += 5))
done
Ich gab nach einer Weile auf und schrieb dies in ungefähr 15 Sekunden in BASIC:
10 count = 375
20 print count
30 count = count+5
40 if count < 3500 then goto 20
Wie kann ich mein BASIC-Programm in einem Bash-Skript erstellen?
Antworten:
Alternativ kann eine traditionelle C-förmige for-Schleife verwendet werden:
Dies ist vielleicht weniger klar als die Verwendung von seq, aber es entstehen keine Unterprozesse. Obwohl ich mit C vertraut bin, hätte ich keine Schwierigkeiten, dies zu verstehen, aber YMMV.
quelle
dash
unterstützt es zumindest nicht. @ChrisDown - Es gibt keinen Grund , warum „POSIX sh“ hat „keine seq“ bedeuten. Aber ja, zugegeben, ich hatte die Tatsache übersehen, dass seq nicht von POSIX spezifiziert wird.Da Sie die Klammererweiterung ohnehin verwenden, sollten Sie die Funktion voll ausnutzen:
Sie können diese Technik auch verwenden, um jede Zahl in einer separaten Zeile mit optionalem Text zu drucken, indem Sie
printf
anstelle vonecho
beispielsweise Folgendes verwenden:Bearbeiten
Wie von @kojiro im Kommentar hervorgehoben, verwendet Mac OS Bash 3 als Standard-Shell, die keine Erhöhung des Sequenzausdrucks der Klammererweiterung unterstützt. Sie müssen auf Bash Version 4 aktualisieren oder eine andere Shell verwenden, die dies unterstützt (z. B. aktuelles zsh).
quelle
bash -c
so gut wie erfolgreich sind, garantiert, dass zwei verschiedene Shells beteiligt sind. Sagt$SHELL --version
, es ist Bash 3?bash
dieser Funktion eingeführt wurde. Ich habe es selbst aus dem Kojiro-Kommentar gelernt. Und bitte vergleichen Sie mich nicht mit SC, ich kenne wirklich nicht alle Details und die Geschichte aller Muscheln seit Ende 1970. Noch einmal - Wenn Sie das erwarten, stimmen Sie einfach ab.Verwenden von SEQ (1)
Oder einfach:
quelle
seq 375 5 3500
.Ihr For-Loop-Snippet hat aus zwei Gründen nicht wie gewünscht funktioniert:
(($i += 5))
- hier$i
wird das auf den Wert von erweiterti
. Daher wird die Erweiterung so etwas wie etwas sein((375 += 5))
, was keinen Sinn ergibt (der Versuch, einer anderen Literalzahl eine Literalzahl zuzuweisen). Dies würde normalerweise erreicht werden mit((i += 5))
(nein$
, um die Variable zu erweitern){375..3500}
wird vor der ersten Iteration der Schleife erweitert. Es wird die Liste der Zahlen sein375 376 ... 3499 3500
.i
Wird für jede Iteration der Schleife jeder dieser Nummern einzeln zugewiesen. Somit wird zu Beginn jeder Iterationi
der nächste Wert in dieser Liste neu zugewiesen, wobei in Schritten von 1((i += 5))
hochgezählt wird. Das macht effektiv nichts - es addiert 5 zu i, aber dann wird i einfach zu Beginn der Iteration neu zugewiesen nächste Iteration.Ich denke, die
for (( ; ; ))
Antwort gefällt mir am besten, aber hier sind einige Alternativen, die Sie zum Nachdenken anregen:Da es sich um ein Vielfaches von 5 handelt und die
{a..b..i}
Erweiterung in Bash-Version 3.2.57 (1) (in OS X) nicht unterstützt wird, können wir stattdessen diese etwas arkane Sache tun:Dies zeigt, wie mit Bash ein kartesisches Produkt erstellt werden kann.
Ich denke, im Allgemeinen ist eine for-Schleife der bequemste Weg, dies zu tun, aber wenn Sie interessiert sind, können Sie ein while-Schleifenprogramm (etwas näher an Ihrem BASIC) verwenden:
quelle
38
bis349
. Auf der zweiten Seite nur zwei Zahlen:0
und5
. Nun können geordnete Paare dieser alle Kombinationen erstellen - man kann sie als Sätze schreiben:{38,0}
,{38,5}
...{349,5}
, oder einfach nur redundante Symbole entfernen{
,,
und}
und bekommen ... neue Zahlen380
...3495
.Natürlich gibt es dafür eine App (
seq 375 5 3500
), aber es gibt verschiedene Möglichkeiten, dies über die Befehlszeile zu tun. Während die schnellste und einfachste nur verwendet wirdseq
, sind hier einige andere Optionen:quelle
$(($i % 5))
kann geschrieben werden$((i % 5))
.POSIXly:
...oder...
Ich weiß nicht, warum du es anders machen würdest. Außer natürlich ...
... oder mit
dc
:quelle
dc
Code funktioniert. Es ist sicherlich faszinierender als die Verwendungseq
.s
Aves die[
Zeichenfolge]
an den oberen Rand desp
Array, dannl
OADS es zurück auf die Oberseite des Stapels und ex
ecutes es als ein Makro. Im Makro drücken wir5
auf den Stapel dann Pop und die zweite von oben und+
sie ersetzen die beiden Stapel Werte mit deren Summe, welchep
rinted undd
vor uplicated3500
auf den Stapel geschoben wird , wenn wir es knallen und die Betrogene wir gerade gemacht für Vergleich>
. Wenn3500
größer ist, laden wir die imp
Array (unserem aktuellen Makro) gespeicherte Zeichenfolge und führen sie als Makro aus , oder wenn nicht, brechen sie.Wenn Sie auf Bash 3 stecken:
und wenn Sie es vorziehen
awk
:Ich wusste nichts über Zahnspangenerweiterung - das ist wirklich cool.
quelle