Как создать диапазон с шагом n в bash? (сгенерировать последовательность чисел с приращениями)


149

Способ перебора диапазона в bash:

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

Каким будет синтаксис для перебора последовательности с шагом? Скажем, я хотел бы получить только четное число в приведенном выше примере.


Четные числа, умножьте i на 2.: P
Джоуи Роберт

умножение довольно уродливое, я бы сказал
SilentGhost

2
@Omnifarious Я бы не был так уверен. Например, OS X по-прежнему поставляется с 3.2. Я бы сказал, что цикл в стиле C.
Эли Корвиго 05

Ответы:


202

я бы сделал

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

(хотя, конечно, сам по себе seq 0 2 10выдаст тот же результат).

Обратите внимание, что seqдопускаются числа с плавающей запятой (например, seq .5 .25 3.5), но расширение скобок bash допускает только целые числа.


4
Рискну предположить, что отрицательное голосование произошло из-за того, что ваш ответ был общим для «sh», а не специфичным для «bash». Чистый подход Bash {begin end step} работает немного лучше. Старый метод seq удобен для старых систем или систем с меньшим объемом памяти, таких как busybox. Я поддержал и ваш ответ, и ответ TheBonsai. :)
Скотт Прайв

7
Предпочитать обратные кавычки $ (...). Обратные кавычки не подходят.
Omnifarious

seq 1000000 1000010, на самом деле, делает только числа с плавающей запятой - нет никакого способа заставить его делать целые числа! Расширение скобок работает.
hmijail оплакивает уволившихся

119

Расширение скобок в Bash 4 имеет ступенчатую функцию:

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

Независимо от того, является ли Bash 2/3 (цикл for в стиле C, см. Ответы выше) или Bash 4, я бы предпочел что-нибудь, а не команду seq.


1
и, кстати, знаете ли вы, что bash4 используется по умолчанию в любой основной ОС?
SilentGhost 08

3
Bash4 все еще не является мейнстримом, нет. Почему не seq? Что ж, скажем это словами бота в IRC-канале #bash: «seq (1) - очень нестандартная внешняя команда, используемая для подсчета до 10 в глупых инструкциях Linux».
TheBonsai 08

Насколько я понимаю, seq является частью coreutils. что в нем нестандартного? аргументы? Спасибо за вашу помощь.
SilentGhost 08

4
Эти аргументы могут иметь значение, а могут и не учитываться: * достаточно систем без GNU coreutils (но установлен Bash) * вы создаете ненужный внешний процесс * вы полагаетесь на идею, что все 'seq' делают то же, что и ваш 'seq' * это не стандартизирован ISO
TheBonsai 08

3
@becko Если шаг сохранен в переменной i, вы не можете этого сделать for {0..10..${i}}.. он терпит неудачу.
Nehal J Wani

75

Чистый Bash, без дополнительных процессов:

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

10
+1 Потому что шаг тоже можно заменить переменной.
Nehal J Wani

1
Я думаю, что это действительно то, чего, вероятно, хочет большинство людей - простой способ сделать цикл с заданным значением шага. Это звучит проще, чем все ответы на основе seq, и имеет более четкий синтаксис, чем расширение скобок Bash4, и похоже, что он допускает переменные (я этого не пробовал, но синтаксис определенно предполагает это).
tobylaroni 05

Работает в Bash 3, в отличие от ответа @ TheBonsai.
srcerer

Он даже разрешает переменную ((i = "$ first"; i <= "$ last"; i + = "$ step")). Не все так просто с фигурными скобками и секв.
Blaa_Thor

Иногда это намного быстрее, чем {0..10..2}-style, например, когда диапазон действительно велик.
Руслан

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

seq - это команда Linux. Это не будет доступно в Mac OS X или FreeBSD.
Dereckson

5
FWIW seq доступен в моей стандартной OS X Mavericks 10.9.1
Марк Сетчелл,

Я попробовал другой синтаксис, но это единственный, который работает у меня на небольшой CentOS. @z - меня спасло: D
m3nda

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.