Как вы используете суффикс строки в bash с использованием отрицательных смещений?

Я пытаюсь взять суффикс строки в Bash с помощью синтаксиса подстроки ${string:pos}, но я не могу понять, почему это не сработает. Мне удалось упростить код примера:

STRING="hello world"

POS=4
echo ${STRING:POS} # prints "o world"
echo ${STRING:4}   # prints "o world"

POS=-4
echo ${STRING:POS} # prints "orld"
echo ${STRING:-4}  # prints "hello world"

Первые три строки работают точно так, как я ожидал, но почему последняя строка печатает "hello world" вместо "orld"?

Ответ 1

Потому что :- - синтаксис расширения параметров для "Использовать значения по умолчанию".

Из документация:

Если не выполняется расширение подстроки, используя описанную форму ниже (например, ':-), Bash тесты для параметра, который отключен или нуль.

Итак, выполнив ${STRING:-4}, вы действительно просите Bash расширить STRING и если он не установлен (никогда не назначался раньше) или null (нулевая строка, напечатанная как ''), она заменит расширение на 4. В вашем примере STRING установлен и, следовательно, расширен до его значения.

Как говорится в другом ответе, вам нужно вызвать поведение по умолчанию, руководство указывает его:

Обратите внимание, что отрицательное смещение должно быть отделено от двоеточия на хотя бы одно пространство, чтобы избежать путаницы с: - расширением.

Например:

${STRING:(-4)}
${STRING: -4}

Ответ 2

Вам нужно "избежать" параметров, начиная с тире с помощью скобки или пробела, иначе bash будет рассматривать его как обычную строку:

echo ${STRING:(-4)}
echo ${STRING: -4}