Как правильно растянуть скобки в «для цикла» BASH для позиционных параметров? - PullRequest
1 голос
/ 07 мая 2019

Когда я пытаюсь написать эту функцию в BASH

function Odds () for i in {1..${#@}..2} ; do echo $i; done

Я ожидал такого вывода, как

1 3 5 ...

в зависимости от количества аргументов, переданных функции.

Но эффективный вывод - это строка с расширенным $ {# @}.

Пример

{1..5..2}

У меня есть некоторые предположения, но ... что-нибудь ... что происходити как этого избежать и получить желаемый результат?

Ответы [ 2 ]

1 голос
/ 07 мая 2019

Проблема в том, что расширение скобки выполняется до замены параметров .Следовательно, расширение скобки нельзя использовать с переменными.

Опция 1: seq

Если у вас установлен seq (это часто встречается в Linux), попробуйте:

function Odds () { seq 1 2 "${#@}"; }

seq 1 2 "${#@}" возвращает числа, начинающиеся с 1 и увеличивающиеся на 2 каждый раз, пока не будет достигнут ${#@}.

Например:

$ Odds a b c d e
1
3
5

Примечание: Обозначение function не является необходимым и ограничивает совместимость (это не POSIX).Odds можно определить без него:

Odds () { seq 1 2 "${#@}"; }

Опция 2: bash

В качестве альтернативы, просто используя bash, определите:

function Odds () { for ((i=1; i<=${#@}; i=i+2)); do echo "$i"; done; }

Это выдаст тот же результат:

$ Odds a b c d e
1
3
5

Вариант 3: POSIX

Для максимальной совместимости используйте функцию, соответствующую стандарту POSIX:

Odds() { i=1; while [ "$i" -le "$#" ]; do echo "$i"; i=$((i+2)); done; }
1 голос
/ 07 мая 2019

Попробуйте это:

function Odds () { for i in {1..${@}..2} ; do echo $i; done }

или

function Odds () { for i in {1..${1}..2} ; do echo $i; done }
...