J'essayais de faire un script bash très simple pour lister tous les multiples de cinq entre 375 et 3500 (375, 380, 385 ...). Une chose que j'ai essayée et qui n'a pas fonctionné est:
for i in {375..3500}
do
echo $i
(($i += 5))
done
J'ai abandonné après un certain temps et j'ai écrit ceci en BASIC en environ 15 secondes:
10 count = 375
20 print count
30 count = count+5
40 if count < 3500 then goto 20
Comment puis-je créer mon programme BASIC dans un script bash?
Réponses:
Alternativement, une boucle de style C traditionnelle peut être utilisée:
C'est peut-être moins clair que d'utiliser seq, mais cela ne génère aucun sous-processus. Bien que je connaisse C, je n'aurais aucune difficulté à comprendre cela, mais YMMV.
la source
dash
ne le prend pas en charge. @ChrisDown - Il n'y a aucune raison « sh Posix » a impliquer « non seq ». Mais oui, d'accord, j'avais oublié que SEQ n'était pas spécifié par POSIX.Puisque vous utilisez l'expansion d'accolade de toute façon, utilisez pleinement sa fonctionnalité:
Vous pouvez également utiliser cette technique pour imprimer chaque numéro sur une ligne distincte avec du texte facultatif en utilisant à la
printf
place deecho
, par exemple:Éditer
Comme l'a souligné @kojiro dans le commentaire, Mac OS utilise bash 3 comme shell par défaut, qui ne prend pas en charge l'expression incrémentielle dans la séquence de l'expansion d'accolade. Vous devez mettre à niveau vers bash version 4 ou utiliser un autre shell qui prend en charge cela (par exemple, zsh récent).
la source
bash -c
peu près à garantir que deux obus différents sont impliqués. Dit$SHELL --version
que c'est bash 3?bash
cette fonctionnalité qui a été introduite. Je l'ai moi-même appris du commentaire de kojiro. Et s'il vous plaît, ne me comparez pas avec SC, je ne connais vraiment pas tous les détails et l'historique de tous les obus depuis la fin des années 1970. Encore une fois - Si vous vous attendez à cela, veuillez simplement voter.Utilisation de SEQ (1)
Ou simplement:
la source
seq 375 5 3500
.Votre extrait de boucle n'a pas fonctionné comme vous le souhaitez pour deux raisons:
(($i += 5))
- ici le$i
est étendu à la valeur dei
. Ainsi, l'expansion ressemblera à quelque chose((375 += 5))
qui n'a pas de sens (essayer d'attribuer un numéro littéral à un autre numéro littéral). Cela serait normalement réalisé avec((i += 5))
(non$
pour étendre la variable){375..3500}
sera développé avant la première itération de la boucle. Ce sera la liste des numéros375 376 ... 3499 3500
. Pour chaque itération de la boucle,i
sera attribué à chacun de ces numéros, un par un. Ainsi, au début de chaque itération,i
sera réaffecté à la valeur suivante de cette liste, en comptant par étapes de 1. Le((i += 5))
fait ne fait rien - il ajoute 5 à i, mais i est simplement réaffecté à nouveau au début de la prochaine itération.Je pense que j'aime
for (( ; ; ))
mieux la réponse, mais voici quelques alternatives pour vous faire réfléchir:Étant donné que nous avons affaire à des multiples de 5 et que l'
{a..b..i}
expansion n'est pas prise en charge dans la version bash 3.2.57 (1) (sous OS X), nous pouvons plutôt faire cette chose légèrement arcanique:Cela montre comment bash peut être utilisé pour créer un produit cartésien.
Je pense qu'en général, une boucle for est le moyen le plus pratique de le faire, mais si vous êtes intéressé, vous pouvez utiliser un programme de boucle while (un peu plus proche de votre BASIC):
la source
38
jusqu'à349
. Au second, seuls deux chiffres:0
et5
. Maintenant nous allons créer couples de ces toutes les combinaisons - vous pouvez les écrire comme des ensembles:{38,0}
,{38,5}
...{349,5}
ou simplement supprimer les symboles redondants{
,,
et}
et obtenir de nouveaux numéros ...380
...3495
.Bien qu'il existe, bien sûr, une application pour cela (
seq 375 5 3500
), il existe différentes façons de le faire à partir de la ligne de commande. Alors que les plus rapides et les plus simples seront simplement en train d'utiliserseq
, voici quelques autres options:la source
$(($i % 5))
peut être écrit$((i % 5))
.POSIX:
...ou...
Je ne sais pas pourquoi tu le ferais autrement. Sauf, bien sûr ...
... ou avec
dc
:la source
dc
code. C'est certainement plus intrigant que d'utiliserseq
.s
la[
chaîne]
en haut dup
tableau, puis lal
remet en haut de la pile et lax
modifie en macro. Dans la macro, nous poussons5
sur la pile, puis la faisons éclater et la seconde à partir du haut et d'+
eux, en remplaçant les deux valeurs de la pile par leur somme, qui estp
imprimée etd
reproduite avant d'3500
être poussée sur la pile, lorsque nous la sautons et la dupe que nous venons de faire pour comparaison>
. Si3500
est supérieur, nous chargeons et exécutons en tant que macro la chaîne stockée dans lep
tableau (notre macro actuelle) , ou sinon nous la cassons.Si vous êtes bloqué sur Bash 3:
et si vous préférez
awk
:Je ne connaissais pas l'expansion des orthèses - c'est vraiment cool.
la source