Bash parameter expansion
up vote
1
down vote
favorite
I have read/been told that in Bash (4+ in my case) that all parameter expansion functions that are available on strings are available on arrays. Today I was trying to setup a function similar to an array pop. I used something similar to the following syntax:
declare -a arr=( 0 1 2 3 4 5 )
arr=( ${arr[@]:0:(-1)} )
Unexpectedly Bash complained with:
-bash: (-1): substring expression < 0
When I do this with a string the syntax works as expected. For example:
var="see spot run"
var="${var:0:(-1)}"
echo "$var"
see spot ru
I know that for the array I could do this instead (and I tested that it works):
declare -a arr=( 0 1 2 3 4 5 )
arr=( ${arr[@]:0:((${#arr[@]}-1))} )
echo ${arr[@]}
0 1 2 3 4
The questions is if all string parameter expansions work on arrays why doesn't the (-1) syntax work as I expect? Am I just over looking something simple here or is there something deeper at play I am missing?
bash
add a comment |
up vote
1
down vote
favorite
I have read/been told that in Bash (4+ in my case) that all parameter expansion functions that are available on strings are available on arrays. Today I was trying to setup a function similar to an array pop. I used something similar to the following syntax:
declare -a arr=( 0 1 2 3 4 5 )
arr=( ${arr[@]:0:(-1)} )
Unexpectedly Bash complained with:
-bash: (-1): substring expression < 0
When I do this with a string the syntax works as expected. For example:
var="see spot run"
var="${var:0:(-1)}"
echo "$var"
see spot ru
I know that for the array I could do this instead (and I tested that it works):
declare -a arr=( 0 1 2 3 4 5 )
arr=( ${arr[@]:0:((${#arr[@]}-1))} )
echo ${arr[@]}
0 1 2 3 4
The questions is if all string parameter expansions work on arrays why doesn't the (-1) syntax work as I expect? Am I just over looking something simple here or is there something deeper at play I am missing?
bash
add a comment |
up vote
1
down vote
favorite
up vote
1
down vote
favorite
I have read/been told that in Bash (4+ in my case) that all parameter expansion functions that are available on strings are available on arrays. Today I was trying to setup a function similar to an array pop. I used something similar to the following syntax:
declare -a arr=( 0 1 2 3 4 5 )
arr=( ${arr[@]:0:(-1)} )
Unexpectedly Bash complained with:
-bash: (-1): substring expression < 0
When I do this with a string the syntax works as expected. For example:
var="see spot run"
var="${var:0:(-1)}"
echo "$var"
see spot ru
I know that for the array I could do this instead (and I tested that it works):
declare -a arr=( 0 1 2 3 4 5 )
arr=( ${arr[@]:0:((${#arr[@]}-1))} )
echo ${arr[@]}
0 1 2 3 4
The questions is if all string parameter expansions work on arrays why doesn't the (-1) syntax work as I expect? Am I just over looking something simple here or is there something deeper at play I am missing?
bash
I have read/been told that in Bash (4+ in my case) that all parameter expansion functions that are available on strings are available on arrays. Today I was trying to setup a function similar to an array pop. I used something similar to the following syntax:
declare -a arr=( 0 1 2 3 4 5 )
arr=( ${arr[@]:0:(-1)} )
Unexpectedly Bash complained with:
-bash: (-1): substring expression < 0
When I do this with a string the syntax works as expected. For example:
var="see spot run"
var="${var:0:(-1)}"
echo "$var"
see spot ru
I know that for the array I could do this instead (and I tested that it works):
declare -a arr=( 0 1 2 3 4 5 )
arr=( ${arr[@]:0:((${#arr[@]}-1))} )
echo ${arr[@]}
0 1 2 3 4
The questions is if all string parameter expansions work on arrays why doesn't the (-1) syntax work as I expect? Am I just over looking something simple here or is there something deeper at play I am missing?
bash
bash
edited Nov 20 at 13:56
Rui F Ribeiro
38.2k1475125
38.2k1475125
asked Nov 20 at 12:09
EnterUserNameHere
7818
7818
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
up vote
2
down vote
accepted
The answer to this question seems to be that NOT ALL string parameter expansions work on arrays. After reviewing the comments and reading the Bash Reference Manual (link provided by don_crissti, thanks) there is a caveat for negative indexing on substring expansion. As noted in the Bash manual (Shell Parameter Expansion):
${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 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.
As pointed out by don_crissti, the length evaluation that is done here is not in reference to the length of the string/substring but rather evaluation performed during the assignment of the length attribute. As in don_crissti's example:
a=2
printf %s\n "${arr[@]:3:(a+1)}"
If the arithmetic evaluation portion of the length assignment (a+1) were to result in a negative value or, as in my case, the value itself were statically passed as a negative number it is an expansion error. That being said both of the following would result in an expansion error:
declare -a arr=( 0 1 2 3 4 5 )
# length evaluates to (-1)
a=2
printf %s\n "${arr[@]:3:(a-3)}"
-bash: (a-3): substring expression < 0
# or length is assigned as (-1)
arr=( ${arr[@]:0:(-1)} )
-bash: (-1): substring expression < 0
Per the Bash manual, this is the expected behavior in both cases.
add a comment |
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
2
down vote
accepted
The answer to this question seems to be that NOT ALL string parameter expansions work on arrays. After reviewing the comments and reading the Bash Reference Manual (link provided by don_crissti, thanks) there is a caveat for negative indexing on substring expansion. As noted in the Bash manual (Shell Parameter Expansion):
${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 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.
As pointed out by don_crissti, the length evaluation that is done here is not in reference to the length of the string/substring but rather evaluation performed during the assignment of the length attribute. As in don_crissti's example:
a=2
printf %s\n "${arr[@]:3:(a+1)}"
If the arithmetic evaluation portion of the length assignment (a+1) were to result in a negative value or, as in my case, the value itself were statically passed as a negative number it is an expansion error. That being said both of the following would result in an expansion error:
declare -a arr=( 0 1 2 3 4 5 )
# length evaluates to (-1)
a=2
printf %s\n "${arr[@]:3:(a-3)}"
-bash: (a-3): substring expression < 0
# or length is assigned as (-1)
arr=( ${arr[@]:0:(-1)} )
-bash: (-1): substring expression < 0
Per the Bash manual, this is the expected behavior in both cases.
add a comment |
up vote
2
down vote
accepted
The answer to this question seems to be that NOT ALL string parameter expansions work on arrays. After reviewing the comments and reading the Bash Reference Manual (link provided by don_crissti, thanks) there is a caveat for negative indexing on substring expansion. As noted in the Bash manual (Shell Parameter Expansion):
${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 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.
As pointed out by don_crissti, the length evaluation that is done here is not in reference to the length of the string/substring but rather evaluation performed during the assignment of the length attribute. As in don_crissti's example:
a=2
printf %s\n "${arr[@]:3:(a+1)}"
If the arithmetic evaluation portion of the length assignment (a+1) were to result in a negative value or, as in my case, the value itself were statically passed as a negative number it is an expansion error. That being said both of the following would result in an expansion error:
declare -a arr=( 0 1 2 3 4 5 )
# length evaluates to (-1)
a=2
printf %s\n "${arr[@]:3:(a-3)}"
-bash: (a-3): substring expression < 0
# or length is assigned as (-1)
arr=( ${arr[@]:0:(-1)} )
-bash: (-1): substring expression < 0
Per the Bash manual, this is the expected behavior in both cases.
add a comment |
up vote
2
down vote
accepted
up vote
2
down vote
accepted
The answer to this question seems to be that NOT ALL string parameter expansions work on arrays. After reviewing the comments and reading the Bash Reference Manual (link provided by don_crissti, thanks) there is a caveat for negative indexing on substring expansion. As noted in the Bash manual (Shell Parameter Expansion):
${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 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.
As pointed out by don_crissti, the length evaluation that is done here is not in reference to the length of the string/substring but rather evaluation performed during the assignment of the length attribute. As in don_crissti's example:
a=2
printf %s\n "${arr[@]:3:(a+1)}"
If the arithmetic evaluation portion of the length assignment (a+1) were to result in a negative value or, as in my case, the value itself were statically passed as a negative number it is an expansion error. That being said both of the following would result in an expansion error:
declare -a arr=( 0 1 2 3 4 5 )
# length evaluates to (-1)
a=2
printf %s\n "${arr[@]:3:(a-3)}"
-bash: (a-3): substring expression < 0
# or length is assigned as (-1)
arr=( ${arr[@]:0:(-1)} )
-bash: (-1): substring expression < 0
Per the Bash manual, this is the expected behavior in both cases.
The answer to this question seems to be that NOT ALL string parameter expansions work on arrays. After reviewing the comments and reading the Bash Reference Manual (link provided by don_crissti, thanks) there is a caveat for negative indexing on substring expansion. As noted in the Bash manual (Shell Parameter Expansion):
${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 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.
As pointed out by don_crissti, the length evaluation that is done here is not in reference to the length of the string/substring but rather evaluation performed during the assignment of the length attribute. As in don_crissti's example:
a=2
printf %s\n "${arr[@]:3:(a+1)}"
If the arithmetic evaluation portion of the length assignment (a+1) were to result in a negative value or, as in my case, the value itself were statically passed as a negative number it is an expansion error. That being said both of the following would result in an expansion error:
declare -a arr=( 0 1 2 3 4 5 )
# length evaluates to (-1)
a=2
printf %s\n "${arr[@]:3:(a-3)}"
-bash: (a-3): substring expression < 0
# or length is assigned as (-1)
arr=( ${arr[@]:0:(-1)} )
-bash: (-1): substring expression < 0
Per the Bash manual, this is the expected behavior in both cases.
edited Nov 21 at 12:10
ilkkachu
54k782147
54k782147
answered Nov 21 at 11:36
EnterUserNameHere
7818
7818
add a comment |
add a comment |
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f482961%2fbash-parameter-expansion%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown