Reputation: 27425
I'm experimenting with bash scripting and noticed the following behavior:
file="test.jar"
echo "${file: -4}" #prints .jar
echo "${file:-4}" #prints test.jar
Very confusing behavior actually. Can someone explain why the second case prints the whole test.jar
?
Upvotes: 2
Views: 56
Reputation: 52361
This is a compromise due to the timeline of features being added to Bash.
${parameter:-word}
or ${parameter-word}
syntax for "replace parameter
with word
if parameter
is null or unset (:-
) / null (-
)" was around for pretty much always; the -
version was already in the Version 7 Bourne Shell.${parameter:offset:length}
and ${parameter:offset}
syntax for "substring of parameter
starting at offset
(with optional length length
)" was introduced in Bash 2.0 (no conflict so far).Negative offsets and length specifications for the substring construct were introduced in Bash 4.2. This leads to a problem:
$ string=01234567890abcdefgh
$ echo ${string:7:-2} # Not ambiguous
7890abcdef
$ echo ${string:-7} # Interpreted as "undefined/null, or..."
01234567890abcdefgh
$ echo ${string: -7} # Interpreted as offset from the end
bcdefgh
$ echo ${string:(-7)} # Interpreted as offset from the end
bcdefgh
The space before -
or the parentheses around the negative offset are there to tell the expansion apart from the :-
(default value) expansion.
If the space is not there, the expansion ${file:-4}
is interpreted as "print 4
if the parameter file
is null or unset, and the expansion of file
otherwise".
References:
Upvotes: 1
Reputation: 36431
This is due to inconsistent syntax. {"string":-}
means default (all the string), whatever follows -
. So you need either a space or parenthesis:
{"string": -4}
{"string":(-4)}
Read bash string manipulation.
Upvotes: 3