Есть ли стандартная программа unix, которая возвращает диапазон чисел

22

Я изучаю сценарии оболочки из устаревшего учебника, и мне кажется, было бы очень полезно иметь программу, которая просто возвращает строку чисел, разделенных пробелами, что-то вроде

$ range 10 20
10 11 12 13 14 15 16 17 18 19 20

Затем, если вы делаете сценарий оболочки, вы можете иметь

for i in `range 10 20`; do some stuff with numbers in that range;done

такая вещь существует, или мне нужно написать это самому?

MYV
источник
когда вы говорите «Unix», вы действительно имеете в виду Linux? Или вы действительно заинтересованы в переносимости на другие системы (Solaris, BSD, ...)?
Гленн Джекман
2
s / range / seq - заменить rangeна seqв вашем примере. по умолчанию используется разделитель новой строки с пробелами:seq -s " " 10 20
n611x007
@naxa В цикле не имеет значения, пробелы или переводы строк, forили даже любая общая команда, которая разделяет аргументы, если вы не установили IFS по-другому.
slhck
1
Этот вопрос должен определить, что означает «стандартная программа Unix» для OP.
Дэвид Риверс
1
Как уже прокомментировал @DavidRivers, вы должны указать в заголовке и вопрос, который вы сосредоточили на дистрибутивах Linux. Ответ, который вы приняли, предлагает инструмент, который НЕ является стандартной программой Unix. Несколько Unix отсутствуют, так seqкак это не указано в POSIX.
Jlliagre

Ответы:

79

seq является частью coreutils.

for i in $( seq 1 2 11 ) ; do echo $i ; done

Выход:

1
3
5
7
9
11

Если вы предоставляете только 2 аргумента seq, приращение составляет 1:

$ seq 4 9
4
5
6
7
8
9
choroba
источник
2
sedтакже есть хорошие опции, такие как -sустановить разделитель или -wопределить ширину. И вы можете предоставить приращение: seq -w -s ", " 0 5 20результаты в 00, 05, 10, 15, 20 .
Scai
2
@ scai ты имел ввиду seq?
Карлос Кампдеррос
@ CarlosCampderrós Конечно, к сожалению, я больше не могу редактировать свой комментарий.
Scai
3
seq 10 20также может быть простой пример, который стоит добавить;)
Der Hochstapler
@ scai, это круто, я узнал кое-что новое сегодня :), честно говоря, я думаю, вы должны добавить это как отдельный, более подробный ответ!
Тим Греневельд
33

Достаточно ли Bash?

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

Вы можете сделать много вещей с расширением скобки . Bash 4 также поддерживает мягкие диапазоны, например{01..20} .

Обратите внимание, что Bash не считается переносимым и не является стандартной утилитой Unix. Хотя вы можете с уверенностью предположить, что он установлен в большинстве современных Linux, не используйте его в сценарии, который планируется запустить на всех типах Unix-подобных машин.

slhck
источник
13
@Maksim: Хотя я предпочитаю это расширение распорки, есть также типичный Un * х инструмент (сделать очень мало, но делать это хорошо) для этого: seq. Использование же, как в вашем примере: seq -s " " 10 20. -sПараметр необходим, так как по умолчанию значения отделены друг от друга \n.
mpy
Да, Баш не «стандартный», в зависимости от того, насколько строго вы это интерпретируете. Мне просто легче с этим обращаться, и это не требует дополнительного звонка.
Slhck
1
@mpy, обратите внимание, что seqэто утилита GNU, и, следовательно, не «стандартная программа Unix»
Гленн Джекман
5
@glennjackman Согласно developer.apple.com/library/Mac/documentation/Darwin/Reference/… ... "Команда seq впервые появилась в Plan 9 в Bell Labs. Команда seq появилась в NetBSD 3.0 и перенесена в FreeBSD 9.0 . Эта команда была основана на одноименной команде Plan 9 от Bell Labs и основных утилит GNU. Команда GNU seq впервые появилась в выпуске утилит оболочки 1.13. "
200_success
Также обратите внимание, что вы можете сделать, for i in {001..010}; ... ; doneи он будет нуля номер до 3 цифр.
VolatileDream
9

Если вы хотите что-то строго переносимое (то есть это не зависит от конкретных расширений bash или команд, не указанных в POSIX)

awk 'BEGIN {for(i=10;i<=20;i++) printf "%d ",i; print}'
jlliagre
источник
1
Вам не нужно добавлять /dev/nullили < /dev/nullк этому?
Скотт
1
@ Скотт Нет, это не обязательно. Стандарт POSIX ( pubs.opengroup.org/onlinepubs/9699919799/utilities/… ) определяет:If the awk program contains no actions and no patterns, but is otherwise a valid awk program, standard input and any file operands shall not be read and awk shall exit with a return status of zero.
jlliagre
6

До 10.7 не было seqна Mac OS X, ноjot , из-за наследия BSD.

jot -- print sequential or random data

...

HISTORY
    The jot utility first appeared in 4.2BSD

Пример:

$ jot - 1 3
1
2
3
Мик
источник
2

Используйте forцикл

for ((i = 10; i <= 20; ++i)); do
    printf '%d\n' "$i"
done
user27076
источник
2

Вы можете использовать seq, или если у вас его нет, вы можете написать это самостоятельно:

#!/bin/bash
[ $# -ge 1 ] || { echo "Usage: seq Number [ Number ]" 1>&2 ; exit 1; }
[ $# -eq 1 ] && { [ $1 -gt 1 ] && ./seq $(($1 - 1)) ; echo $1 ; }
[ $# -eq 2 ] && { [ $(($2 - $1)) -gt 0 ] && ./seq $1 $(($2 - 1)) ; echo $2 ; }

Использование:

$ ./seq 3
1
2
3

Или:

$ ./seq 3 7
3
4
5
6
7
StackedCrooked
источник
1

Ради полноты здесь кое-что, что будет работать с некоторыми более старыми вариантами Unix (если на них установлен Perl). Не очень элегантно.

for I in $(perl -e 'print join("\n", 1..10)'); do something with $I; done
Рето
источник