Jak stworzyć zakres z krokiem n w bash? (wygeneruj sekwencję liczb z przyrostami)


143

Sposób na iterację w zakresie w bash to

for i in {0..10}; do echo $i; done

Jaka byłaby składnia iteracji sekwencji z krokiem? Powiedz, chciałbym uzyskać tylko liczbę parzystą w powyższym przykładzie.


Liczby parzyste, pomnóż i przez 2.: P
Joey Robert

mnożenie jest raczej brzydkie, powinienem powiedzieć
SilentGhost

2
@ Omnifarious Nie byłbym taki pewien. Na przykład OS X nadal zawiera wersję 3.2. Powiedziałbym, że pętla w stylu C powinna zostać zaakceptowana.
Eli Korvigo,

Odpowiedzi:


195

mogłabym zrobić

for i in `seq 0 2 10`; do echo $i; done

(choć oczywiście seq 0 2 10sam wyprodukuje ten sam wynik).

Zauważ, że seqdopuszcza liczby zmiennoprzecinkowe (np. seq .5 .25 3.5), Ale rozwinięcie nawiasów klamrowych basha dopuszcza tylko liczby całkowite.


4
Zaryzykuję przypuszczenie, że głos negatywny był spowodowany tym, że twoja odpowiedź była ogólna na „sh”, a nie specyficzna dla „bash”. Czyste podejście Bash {begin end step} działa tylko trochę lepiej. Starsza metoda 'seq' jest przydatna na starszych lub mniejszych systemach pamięci, takich jak busybox. Głosowałem za odpowiedzią zarówno twoją, jak i TheBonsai. :)
Scott Prive

6
Wolę $ (...) zamiast cudzysłowów. Cytaty wsteczne nie zagnieżdżają się normalnie.
Omnifarious

seq 1000000 1000010 robi tylko zmiennoprzecinkowe, właściwie - nie ma sposobu, aby zrobić liczby całkowite! Rozbudowa nawiasów działa.
hmijail opłakuje resignees

112

Rozszerzenie nawiasów klamrowych Bash 4 ma funkcję krokową:

for {0..10..2}; do
  ..
done

Bez względu na to, czy Bash 2/3 (pętla w stylu C, patrz odpowiedzi powyżej) czy Bash 4, wolałbym cokolwiek zamiast polecenia „seq”.


1
i przy okazji, czy wiesz, czy bash4 jest domyślny w jakimkolwiek głównym systemie operacyjnym?
SilentGhost

3
Bash4 nadal nie jest głównym nurtem, nie. Dlaczego nie seq? Cóż, powiedzmy to słowami bota na kanale IRC #bash: „seq (1) to wysoce niestandardowe polecenie zewnętrzne używane do liczenia do 10 w głupich linuksowych instrukcjach”.
TheBonsai

rozumiem, że seq jest częścią coreutils. co w tym niestandardowego? argumenty? dzięki za pomoc.
SilentGhost

4
Te argumenty mogą, ale nie muszą się dla ciebie liczyć: * jest wystarczająco dużo systemów bez jądra GNU (ale zainstalowany Bash) * tworzysz niepotrzebny proces zewnętrzny * polegasz na założeniu, że wszystkie 'seq' robią to, co robi 'seq' * to jest nie znormalizowany przez ISO
TheBonsai

3
@becko Jeśli krok jest przechowywany w zmiennej i, nie możesz tego zrobić for {0..10..${i}}... kończy się niepowodzeniem.
Nehal J Wani

72

Pure Bash, bez dodatkowego procesu:

for (( COUNTER=0; COUNTER<=10; COUNTER+=2 )); do
    echo $COUNTER
done

10
+1 Ponieważ krok można również zastąpić zmienną.
Nehal J Wani

1
Myślę, że to jest to, czego większość ludzi prawdopodobnie chce - prosty sposób na wykonanie pętli z określoną wartością kroku. Brzmi prościej niż wszystkie odpowiedzi oparte na sekwencjach i jest jaśniejszą składnią niż rozwinięcie nawiasów klamrowych Bash4 i wygląda na to, że dopuszcza zmienne (nie próbowałem tego, ale składnia zdecydowanie to sugeruje).
tobylaroni

Działa w Bash 3, w przeciwieństwie do odpowiedzi @ TheBonsai.
srcerer

Rozwiązuje nawet zmienną (((i = "$ first"; i <= "$ last"; i + = "$ step")). Nie tak łatwo z klamrami kręconymi i sekwencją.
Blaa_Thor

20
#!/bin/bash
for i in $(seq 1 2 10)
do
   echo "skip by 2 value $i"
done

seq to polecenie Linuksa. To nie będzie dostępne w systemie Mac OS X ani FreeBSD.
Dereckson

5
Sekwencja FWIW jest dostępna w moim standardowym systemie OS X Mavericks 10.9.1
Mark Setchell

Próbowałem innego sintaxa, ale to jedyny działa na moim małym CentOS. @z - uratował mi dzień: D
m3nda

3
> seq 4
1
2
3
4

> seq 2 5
2
3
4
5

> seq 4 2 12
4
6
8
10
12

> seq -w 4 2 12
04
06
08
10
12

> seq -s, 4 2 12
4,6,8,10,12
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.