2117 Stimmen

Wie kann ich in der Bash über einen durch Variablen definierten Zahlenbereich iterieren?

Wie kann ich in Bash über einen Zahlenbereich iterieren, wenn der Bereich durch eine Variable vorgegeben ist?

Ich weiß, dass ich dies tun kann (in der Bash "Sequenzausdruck" genannt) Dokumentation ):

 for i in {1..5}; do echo $i; done

Das ergibt:

1
2
3
4
5

Doch wie kann ich einen der Endpunkte des Bereichs durch eine Variable ersetzen? Das funktioniert nicht:

END=5
for i in {1..$END}; do echo $i; done

Welche Drucke:

{1..5}

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.

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 wie 01, 02, 03, ..., 10 .

7voto

BashTheKeyboard Punkte 81

Ersetzen Sie {} con (( )) :

tmpstart=0;
tmpend=4;

for (( i=$tmpstart; i<=$tmpend; i++ )) ; do 
echo $i ;
done

Ausbeute:

0
1
2
3
4

7voto

SuperBob Punkte 87

Diese sind alle nett, aber seq ist angeblich veraltet und die meisten arbeiten nur mit numerischen Bereichen.

Wenn Sie Ihre for-Schleife in doppelte Anführungszeichen einschließen, werden die Start- und Endvariablen beim Echo der Zeichenkette dereferenziert, und Sie können die Zeichenkette zur Ausführung direkt an BASH zurückgeben. $i muss mit \'s escaped werden, damit es NICHT ausgewertet wird, bevor es an die Subshell gesendet wird.

RANGE_START=a
RANGE_END=z
echo -e "for i in {$RANGE_START..$RANGE_END}; do echo \\${i}; done" | bash

Diese Ausgabe kann auch einer Variablen zugewiesen werden:

VAR=`echo -e "for i in {$RANGE_START..$RANGE_END}; do echo \\${i}; done" | bash`

Der einzige "Overhead", der dabei entsteht, sollte die zweite Instanz der Bash sein, so dass sie für intensive Operationen geeignet sein sollte.

6voto

Alex Spangher Punkte 927

Wenn Sie Shell-Befehle ausführen und (wie ich) einen Fetisch für Pipelining haben, ist dies eine gute Lösung:

seq 1 $END | xargs -I {} echo {}

3voto

Zimba Punkte 1969

Wenn Sie nicht '' verwenden wollen seq ' oder ' eval ' oder jot oder arithmetisches Expansionsformat z.B.. for ((i=1;i<=END;i++)) oder andere Schleifen, z. B. while und du willst nicht ' printf ' und glücklich bis ' echo ', dann könnte diese einfache Lösung für Ihr Budget geeignet sein:

a=1; b=5; d='for i in {'$a'..'$b'}; do echo -n "$i"; done;' echo "$d" | bash

PS: Meine Bash hat keine ' seq Befehl trotzdem.

Getestet auf Mac OSX 10.6.8, Bash 3.2.48

0voto

Ethan Post Punkte 2970

Dies funktioniert in Bash und Korn, kann auch von höheren zu niedrigeren Zahlen gehen. Wahrscheinlich nicht die schnellste oder schönste Methode, aber sie funktioniert gut genug. Behandelt auch Negative.

function num_range {
   # Return a range of whole numbers from beginning value to ending value.
   # >>> num_range start end
   # start: Whole number to start with.
   # end: Whole number to end with.
   typeset s e v
   s=${1}
   e=${2}
   if (( ${e} >= ${s} )); then
      v=${s}
      while (( ${v} <= ${e} )); do
         echo ${v}
         ((v=v+1))
      done
   elif (( ${e} < ${s} )); then
      v=${s}
      while (( ${v} >= ${e} )); do
         echo ${v}
         ((v=v-1))
      done
   fi
}

function test_num_range {
   num_range 1 3 | egrep "1|2|3" | assert_lc 3
   num_range 1 3 | head -1 | assert_eq 1
   num_range -1 1 | head -1 | assert_eq "-1"
   num_range 3 1 | egrep "1|2|3" | assert_lc 3
   num_range 3 1 | head -1 | assert_eq 3
   num_range 1 -1 | tail -1 | assert_eq "-1"
}

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X