Voici une sorte de pseudo-code pour ce que j'essaie d'accomplir:
#!/bin/bash
# I already have the variable below figured out (positive integer):
numlines=$([returns number of lines containing specific characters in a file])
# This is basically what I want to do with it:
for i in {1..$numlines}; do
# the part below is already figured out as well:
do some other stuff
done
Je peux l'exécuter correctement à partir de la ligne de commande en insérant le nombre réel dans la séquence `{1..n} '. J'ai juste besoin de savoir s'il est possible d'inclure une variable ici et comment s'y prendre.
- Je l' ai essayé
export
ing il - J'ai essayé de mettre la variable elle-même entre accolades dans la séquence:
{1..${numlines}}
- J'ai essayé de le mettre entre guillemets en espérant qu'il se développerait:
{1.."$numlines"}
- J'ai essayé d'échapper à
$
:{1..\$numlines}
Dois-je utiliser une set -[something]
commande pour que cette variable soit développée? J'ai même essayé certaines formes d'utilisation eval
... sans succès.
J'ai juste besoin de savoir s'il y a quelque chose de simple ou obscur qui me manque ou si c'est même possible avant de perdre plus de temps dessus.
Je pourrais mettre au point une manière vraiment, vraiment hackish de le faire pour le faire fonctionner au besoin, mais j'aimerais éviter cela si possible et apprendre la bonne façon de procéder.
la source
Réponses:
Malheureusement, il n'y a aucun moyen d'utiliser une variable dans cette expansion (AFAIK), car l'expansion de variable se produit après l'expansion de l'accolade.
Heureusement, il existe un outil qui fait le même travail.
seq
provient de GNU coreutils; aucune idée de comment le faire dans POSIX.la source
seq
est bon pour les systèmes GNU et, si je me souviens bien, le plus récent OSX. Sur d'autres systèmes BSD, on peut utiliser jot à la place.seq
marche parfaitement. Merci beaucoup pour votre réponse rapide.{16..1}
?$(seq $numlines 1)
n'a pas marché. Je suppose que je peux toujoursman seq
, mais je me demandais simplement si quelqu'un savait par le haut de leur tête.for i in $(seq $numlines -1 1)
seq ${numlines} -1 0
Sûr. Si vous voulez une boucle for qui incrémente une variable entière, utilisez la forme de la
for
boucle qui incrémente une variable entière (ou plus généralement effectue une arithmétique sur la ou les variables de boucle).Cette construction fonctionne en bash (et ksh93 et zsh), mais pas en plain sh. En clair, utilisez une boucle while et la
[ … ]
construction test ( ).la source
Si vous devez éviter
seq
, ce qui, comme le souligne Tom Hunt, semble être la solution habituelle à cela, alors vous pouvezeval
certainement le faire (cependant, je ne l'encouragerais pas):Vous pouvez rester POSIX en évitant l'expansion {}, et faites simplement des comparaisons mathématiques et entières sur
$numlines
:En dehors de Posix,
bash
etksh
etzsh
ont également de style Cfor
boucles:la source
seq
fonctionne bien pour mon scénario et semble être la solution la plus simple, il est bon de savoir qu'il existe d'autres alternatives (même POSIX). Merci pour cela.eval
; si vous avez une extension d'accolade, vous avez la boucle de style C.eval
exemple était le plus simple et m'aurait évité d'avoir à chercher une autre façon de le faire en utilisantseq
. Lawhile
boucle est un peu volumineuse pour moi. J'aime garder les choses courtes et douces, et je n'ai jamais pu faire fonctionner lafor
boucle de style C en donnanti
la valeur 0 ou 1. Elle n'est jamais revenue correctement et était toujours un peu décalée. Je suis sûr qu'il pourrait être modifié pour fonctionner correctement, mais ce sont certainement des solutions utiles, néanmoins.eval
approche est problématique s'il y a quelque chose de non trivial à l'intérieur du corps de la boucle. J'imagine que ce ne serait pas très lisible si vous deviez imbriquer deux de ces boucles.