Unten ist eine Art Pseudocode für das, was ich erreichen möchte:
#!/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
Ich kann es gut über die Befehlszeile ausführen, indem ich die tatsächliche Nummer in die Sequenz "{1..n}" einfüge. Ich muss nur wissen, ob es möglich ist, hier eine Variable einzufügen, und wie es geht.
- Ich habe versucht ,
export
es ing - Ich habe versucht, die Variable selbst in geschweifte Klammern innerhalb der Sequenz zu setzen:
{1..${numlines}}
- Ich habe versucht, es in doppelte Anführungszeichen zu setzen, in der Hoffnung, dass es sich erweitern würde:
{1.."$numlines"}
- Ich habe versucht, dem zu entkommen
$
:{1..\$numlines}
Muss ich einen set -[something]
Befehl verwenden, damit diese Variable erweitert wird? Ich habe sogar einige Formen der Verwendung ausprobiert eval
... alles ohne Erfolg.
Ich muss nur wissen, ob mir etwas Einfaches oder Dunkles fehlt oder ob dies überhaupt möglich ist, bevor ich mehr Zeit damit vergeude.
Ich könnte eine wirklich, wirklich hackige Art und Weise zusammenstellen, damit es nach Bedarf funktioniert, aber ich würde das gerne vermeiden, wenn es überhaupt möglich ist, und lernen, wie man es richtig macht.
quelle
Antworten:
Leider gibt es keine Möglichkeit, eine Variable in dieser Erweiterung (AFAIK) zu verwenden, da die Variablenerweiterung nach der Klammererweiterung erfolgt.
Glücklicherweise gibt es ein Tool, das den gleichen Job macht.
seq
ist von GNU Coreutils; Keine Ahnung, wie es in POSIX geht.quelle
seq
ist gut für GNU-Systeme und, wenn ich mich richtig erinnere, das neueste OSX. Auf anderen BSD-Systemen kann stattdessen Jot verwendet werden.seq
funktioniert perfekt. Vielen Dank für Ihre schnelle Antwort.{16..1}
.$(seq $numlines 1)
funktioniert nicht. Ich denke, ich kann es immerman seq
, aber ich frage mich nur, ob jemand etwas von oben wusste.for i in $(seq $numlines -1 1)
seq ${numlines} -1 0
Sicher. Wenn Sie eine for-Schleife wünschen, die eine Ganzzahlvariable inkrementiert, verwenden Sie die Form der
for
Schleife , die eine Ganzzahlvariable inkrementiert (oder allgemeiner eine Arithmetik für die Schleifenvariablen ausführt).Dieses Konstrukt funktioniert in bash (und ksh93 und zsh), aber nicht in plain sh. Verwenden Sie in plain sh eine while-Schleife und das
[ … ]
Konstrukt test ( ).quelle
Wenn Sie vermeiden müssen
seq
, was, wie Tom Hunt betont, die übliche Lösung dafür zu sein scheint, dann kann eseval
definitiv ein (obwohl ich es nicht fördern würde):Sie können POSIX beibehalten, indem Sie die Erweiterung {} vermeiden und einfach mathematische und ganzzahlige Vergleiche durchführen für
$numlines
:Außerhalb von POSIX,
bash
undksh
undzsh
auch C-Stilfor
Schleifen:quelle
seq
für mein Szenario gut funktioniert hat und die einfachste Lösung zu sein schien, ist es gut zu wissen, dass es andere (sogar POSIX) Alternativen gibt. Danke dafür.eval
; Wenn Sie eine Klammererweiterung haben, haben Sie die Schleife im C-Stil.eval
Beispiel das einfachste und hätte mich davor bewahrt, nach einer alternativen Methode suchen zu müssenseq
. Diewhile
Schleife ist für mich etwas sperrig. Ich mag es, die Dinge kurz und bündig zu halten, und ich konnte die C-artigefor
Schleife nie zum Laufen bringen , indem ichi
den Wert 0 oder 1 angab. Sie kehrte nie richtig zurück und war immer ein wenig daneben. Ich bin sicher, es könnte optimiert werden, um richtig zu funktionieren, aber dies sind definitiv hilfreiche Lösungen.eval
Ansatz ist problematisch, wenn sich im Körper der Schleife etwas nicht Triviales befindet. Ich stelle mir vor, es wäre nicht sehr lesbar, wenn Sie zwei solcher Schleifen verschachteln müssten.