Do pracy dostałem następujące rzeczy:
for i in {2..10}
do
echo "output: $i"
done
Produkuje kilka linii output: 2
, output: 3
tak dalej.
Jednak próba uruchomienia następujących czynności:
max=10
for i in {2..$max}
do
echo "$i"
done
produkuje:
output: {2..10}
Jak sprawić, by kompilator zdał sobie sprawę, że $ max powinien traktować jako drugi koniec tablicy, a nie część ciągu?
echo "$i
powinno byćecho "$i"
- jednak nie rozwiąże problemu.do
ithen
słowa kluczowe na tej samej linii,for
iif
, odpowiednio. Np.for i in {2..10}; do
Odpowiedzi:
Rozwinięcie nawiasu klamrowego {x..y} jest wykonywane przed innymi rozszerzeniami, więc nie można go użyć dla sekwencji o zmiennej długości.
Zamiast tego należy użyć
seq 2 $max
metody jako użytkownik mob stwierdził .Na przykład dla przykładu:
źródło
seq
zliczanie i zwiększanie liczb w pętli for, dlatego zaleca się unikanie używaniaseq
. To polecenie pozostawia się do zachowania zgodności ze starą wersją bash. Wbudowane polecenia są wystarczająco szybkie.for (( EXP1; EXP2; EXP3 )) ...
for (( ... ))
składnia nie jest POSIX, co oznacza na przykład, że nie będzie działać od razu po zainstalowaniu w takich systemach jak Alpine Linux.seq
robi.#!/bin/sh
jest Dash w Debian / Ubuntu.Wypróbuj wersję z wyrażeniem arytmetycznym
for
:Jest to dostępne w większości wersji bash i powinno być również kompatybilne z powłoką Bourne'a (sh).
źródło
sh
, zamiast tego link do innej powłoki. Najlepiejsh
byłoby, gdyby wywołano taką powłokę, która obsługiwałaby tylko te funkcje w standardzie POSIX, ale domyślnie przepuszcza niektóre z ich dodatkowych funkcji. Pętla for-style w stylu C nie jest funkcją POSIX, ale może być wsh
trybie przez rzeczywistą powłokę.Krok ręcznie pętli:
Jeśli nie musisz być całkowicie POSIX, możesz użyć arytmetyki dla pętli:
Lub użyj jot (1) w systemach BSD:
źródło
true $(( i++ ))
nie działa we wszystkich przypadkach, więc najbardziej przenośny byłbytrue $((i=i+1))
.Jest na to więcej niż jeden sposób.
źródło
eval
oceni wszystko, co ustawiszmax
. Zastanów sięmax="2}; echo ha; #"
, a następnie zamień naecho ha
coś bardziej destrukcyjnego.Jeśli
seq
polecenie jest dostępne w systemie:Jeśli nie, użyj biednego człowieka
seq
zperl
:Obserwuj te znaki cudzysłowu.
źródło
Oto sposób:
Bash:
Powyższy sposób Bash będzie działał dla
ksh
izsh
, gdybash -c
zostanie zastąpiony odpowiednio przezksh -c
lubzsh -c
.Uwaga:
for i in {2..${max}}; do echo $i; done
działa wzsh
iksh
.źródło
Możemy iterować pętlę jak programowanie C.
źródło
Tutaj działało na Mac OS X.
Obejmuje przykład daty BSD, jak również zwiększać i zmniejszać datę:
źródło
Ponieważ nie miałem
seq
zainstalowanego polecenia w moim systemie (Mac OS X 10.6.1 (Snow Leopard)),while
zamiast tego skorzystałem z pętli:* Wzrusza ramionami * Cokolwiek działa.
źródło
Wszystko to robi
{1..8}
i powinno być POSIX. Nie ulegną również uszkodzeniu, jeśli wpiszesz warunekcontinue
w pętli. Kanoniczny sposób:Inny sposób:
i kolejny:
źródło
Posługiwać się:
Potrzebujesz wyraźnego wywołania „eval”, aby ponownie ocenić {} po podstawieniu zmiennej.
źródło