Чи є стандартна програма 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

чи існує така річ, чи мені це потрібно писати самостійно?


коли ти кажеш "unix", ти справді маєш на увазі Linux? Або вас справді цікавить портативність до інших систем (Solaris, BSD, ...)?
glenn jackman

2
s / діапазон / сл - замінити rangeз seqв вашому прикладі. роздільник за замовчуванням - новий рядок, щоб мати пробіли:seq -s " " 10 20
n611x007

@naxa Чи це пробіли чи нові рядки, це значення не має значення в forциклі - або навіть у будь-якій загальній команді, яка розбиває аргументи - якщо ви не встановили інше IFS.
slhck

1
Це питання повинно визначати, що означає "стандартна програма Unix" для ОП.
Девід Ріверс

1
Як @DavidRivers вже коментував, ви повинні вказати назву та питання, на яке ви зосереджуєтесь на дистрибутивах Linux. Ви прийняли відповідь, що це інструмент, який НЕ є стандартною програмою Unix. Декілька Unix бракує, seqоскільки це не визначено POSIX.
jlliagre

Відповіді:


79

seq входить до основних ядер.

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

Вихід:

1
3
5
7
9
11

Якщо ви наводите лише два аргументи seq, приріст дорівнює 1:

$ seq 4 9
4
5
6
7
8
9

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

Чи вистачить Баша?

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

З розширенням дужок можна зробити багато речей . Bash 4 також підтримує прокладені діапазони, наприклад {01..20}.

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


13
@Maksim: Хоча я вважаю за краще це розширення розпірки, є також типовий Un * х інструмент (зробити дуже мало, але робити це добре) для цього: seq. Використання ж, як у вашому прикладі: seq -s " " 10 20. -sПараметр необхідний, так як за замовчуванням значення відокремлені один від одного \n.
mpy

Так, Баш не "стандартний" залежно від того, наскільки суворо ти це інтерпретуєш. Мені просто зручніше впоратися, і це не вимагає додаткового дзвінка.
slhck

1
@mpy, зауважте, що seqце утиліта GNU, а отже, не "стандартна програма Unix"
glenn jackman

5
@glennjackman За даними developer.apple.com/library/Mac/documentation/Darwin/Reference/… ... "Команда seq вперше з'явилася в" Плані 9 "з Bell Labs. Команда seq з'явилася в NetBSD 3.0 і перенесена на FreeBSD 9.0 . Ця команда була заснована на однойменній команді в Плані 9 від Bell Labs та основних утиліт GNU. Команда послідовності GNU вперше з'явилася у випуску утиліти оболонки 1.13. "
200_успіх

Також зауважте, що ви можете це зробити, for i in {001..010}; ... ; doneі це приведе нуль на 3 цифри.
VolatileDream

9

Якщо ви хочете щось суто портативно (тобто це не покладається на конкретні розширення bash або команди, не визначені POSIX)

awk 'BEGIN {for(i=10;i<=20;i++) printf "%d ",i; print}'

1
Вам не потрібно додавати /dev/nullчи < /dev/nullдо цього?
Скотт

1
@Scott Ні, це не потрібно. Стандарт 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

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

1

Для повноти тут щось, що буде працювати з деякими старими варіантами Unix (до тих пір, поки у них встановлено perl). Не дуже елегантний.

for I in $(perl -e 'print join("\n", 1..10)'); do something with $I; done
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.