Как создать диапазон с шагом 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
z -
источник
seq - это команда Linux. Это не будет доступно в Mac OS X или FreeBSD.
Dereckson
5
FWIW seq доступен в моей стандартной OS X Mavericks 10.9.1
Марк Сетчелл,
Я попробовал другой синтаксис, но это единственный, который работает у меня на небольшой CentOS. @z - меня спасло: D
m3nda
5
> 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
Мир-Исмаилит
источник