LINUX.ORG.RU

(info "(bash) Shell Parameter Expansion")

'${PARAMETER:OFFSET}'
'${PARAMETER:OFFSET:LENGTH}'
     This is referred to as Substring Expansion.  It expands to up to
     LENGTH characters of the value of PARAMETER starting at the
     character specified by OFFSET.  If PARAMETER is '@', an indexed
     array subscripted by '@' or '*', or an associative array name, the
     results differ as described below.  If LENGTH is omitted, it
     expands to the substring of the value of PARAMETER starting at the
     character specified by OFFSET and extending to the end of the
     value.  LENGTH and OFFSET are arithmetic expressions (*note Shell
     Arithmetic::).

     If OFFSET evaluates to a number less than zero, the value is used
     as an offset in characters from the end of the value of PARAMETER.
     If LENGTH evaluates to a number less than zero, it is interpreted
     as an offset in characters from the end of the value of PARAMETER
     rather than a number of characters, and the expansion is the
     characters between OFFSET and that result.  Note that a negative
     offset must be separated from the colon by at least one space to
     avoid being confused with the ':-' expansion.

     Here are some examples illustrating substring expansion on
     parameters and subscripted arrays:

     $ string=01234567890abcdefgh
     $ echo ${string:7}
     7890abcdefgh
     $ echo ${string:7:0}

     $ echo ${string:7:2}
     78
     $ echo ${string:7:-2}
     7890abcdef
     $ echo ${string: -7}
     bcdefgh
     $ echo ${string: -7:0}

     $ echo ${string: -7:2}
     bc
     $ echo ${string: -7:-2}
     bcdef
     $ set -- 01234567890abcdefgh
     $ echo ${1:7}
     7890abcdefgh
     $ echo ${1:7:0}

     $ echo ${1:7:2}
     78
     $ echo ${1:7:-2}
     7890abcdef
     $ echo ${1: -7}
     bcdefgh
     $ echo ${1: -7:0}

     $ echo ${1: -7:2}
     bc
     $ echo ${1: -7:-2}
     bcdef
     $ array[0]=01234567890abcdefgh
     $ echo ${array[0]:7}
     7890abcdefgh
     $ echo ${array[0]:7:0}

     $ echo ${array[0]:7:2}
     78
     $ echo ${array[0]:7:-2}
     7890abcdef
     $ echo ${array[0]: -7}
     bcdefgh
     $ echo ${array[0]: -7:0}

     $ echo ${array[0]: -7:2}
     bc
     $ echo ${array[0]: -7:-2}
     bcdef

     If PARAMETER is '@', the result is LENGTH positional parameters
     beginning at OFFSET.  A negative OFFSET is taken relative to one
     greater than the greatest positional parameter, so an offset of -1
     evaluates to the last positional parameter.  It is an expansion
     error if LENGTH evaluates to a number less than zero.

     The following examples illustrate substring expansion using
     positional parameters:

     $ set -- 1 2 3 4 5 6 7 8 9 0 a b c d e f g h
     $ echo ${@:7}
     7 8 9 0 a b c d e f g h
     $ echo ${@:7:0}

     $ echo ${@:7:2}
     7 8
     $ echo ${@:7:-2}
     bash: -2: substring expression < 0
     $ echo ${@: -7:2}
     b c
     $ echo ${@:0}
     ./bash 1 2 3 4 5 6 7 8 9 0 a b c d e f g h
     $ echo ${@:0:2}
     ./bash 1
     $ echo ${@: -7:0}


     If PARAMETER is an indexed array name subscripted by '@' or '*',
     the result is the LENGTH members of the array beginning with
     '${PARAMETER[OFFSET]}'.  A negative OFFSET is taken relative to one
     greater than the maximum index of the specified array.  It is an
     expansion error if LENGTH evaluates to a number less than zero.

     These examples show how you can use substring expansion with
     indexed arrays:

     $ array=(0 1 2 3 4 5 6 7 8 9 0 a b c d e f g h)
     $ echo ${array[@]:7}
     7 8 9 0 a b c d e f g h
     $ echo ${array[@]:7:2}
     7 8
     $ echo ${array[@]: -7:2}
     b c
     $ echo ${array[@]: -7:-2}
     bash: -2: substring expression < 0
     $ echo ${array[@]:0}
     0 1 2 3 4 5 6 7 8 9 0 a b c d e f g h
     $ echo ${array[@]:0:2}
     0 1
     $ echo ${array[@]: -7:0}


     Substring expansion applied to an associative array produces
     undefined results.

     Substring indexing is zero-based unless the positional parameters
     are used, in which case the indexing starts at 1 by default.  If
     OFFSET is 0, and the positional parameters are used, '$@' is
     prefixed to the list.
Zmicier ★★★★★ ()
Последнее исправление: Zmicier (всего исправлений: 1)

Так работает конечно, но лучше уведите детей от ваших голубых экранов.
${arr[@]::((${#arr[@]}-1))}

d_a ★★★★★ ()
Ответ на: комментарий от d_a

работает

но лучше уведите детей от ваших голубых экранов

почему? есть какие-то нюансы?
я придумал аналог с грепом:

declare -a ALL

ALL=("$@")

declare -a A

A=($(grep -Po ".*(?=${ALL[-1]})"<<<"$@"))

teod0r ★★★★★ ()
Ответ на: комментарий от shdown

Действительно, что-то я обезьяньей лапой нажмякал, в то время как написано выше -- LENGTH and OFFSET are arithmetic expressions.

d_a ★★★★★ ()
Ответ на: комментарий от teod0r

почему? есть какие-то нюансы?

Потому, вон там уже кому-то выше худо сделалось, хотя я же сказал увести всяких таких +_°

d_a ★★★★★ ()
Ответ на: комментарий от teod0r

дело в том, что количество элементов массива не известно

Что значит «не известно»? Так узнайте! $#, если что.

$ set -- 1 2 3 4 5 6 7 8 9 0 a b c d e f g h
$ echo ${@:1:$#-1}
1 2 3 4 5 6 7 8 9 0 a b c d e f g
Zmicier ★★★★★ ()
Ответ на: комментарий от teod0r

я придумал аналог с грепом
A=($(grep -Po ".*(?=${ALL[-1]})"<<<"$@"))

Ужснах.

Zmicier ★★★★★ ()
Ответ на: комментарий от anonymous

+1 обратные индексы задачу сильно облегчают

Обратные индексы облегчают задачу выбора элементов массива по прямым индексам? О_о Или что вы сейчас сказали?

Zmicier ★★★★★ ()

echo $@ | rev | cut -d' ' -f2- | rev

// простите меня.

IPR ★★★★★ ()
Последнее исправление: IPR (всего исправлений: 1)

Можешь сократить кол-во действий, записав все в длинную плохочитаемую строку

a=("$@")
len=${#a[@]}
last=$(($len - 1))
unset a[$last]
 или 
a=("$@")
unset a[$#-1]

futurama ★★★★★ ()
Последнее исправление: futurama (всего исправлений: 1)
Ответ на: комментарий от anonymous

А, понял. Да, конечно. Затрудняюсь сказать, почему их реализовали только для строк, но не массивов. Вы не знаете?

Zmicier ★★★★★ ()
Последнее исправление: Zmicier (всего исправлений: 1)
Ответ на: комментарий от d_a

${arr[@]::((${#arr[@]}-1))}

разве в этих ваших bash индексы не предмет для «arithmetic expansion»? (в смысле круглые скобки глупо писать)

anonymous ()
Ответ на: комментарий от teod0r

В контексте нашей темы — псевдокод для иллюстрации не очень удачного словосочетания «обратный индекс».

Zmicier ★★★★★ ()
Последнее исправление: Zmicier (всего исправлений: 2)
Ответ на: комментарий от Zmicier

а почему когда я делаю для массива конструкцию вида:

 echo "${VAR[@]:1:3}"
чтобы вывести элементы массива с первого по третий, выводит со второго по четвёртый? приходится писать с нулевого по третий. как правильно?

teod0r ★★★★★ ()
Ответ на: комментарий от Zmicier

т.е. в моей ситуации с ноля нужно начинать?
а почему в конце должно быть :3 а не :2 для отображения трёх? ведь если начинать с ноля, то ноль первый, всего 3, т.е. :2 должно быть

teod0r ★★★★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.