OS X 上的 Bash 4.3 子串负长度

Bre*_*ust 15 bash string-manipulation

Bash 4.2 添加了对负子字符串长度的支持:

http://tldp.org/LDP/abs/html/abs-guide.html#SUBSTREXTR01

例 37-12。字符串提取构造中的负参数

当“length”参数为负数时,它用作偏移量参数。

例如,在 Ubuntu 上测试时输出“World”:

STR="Hello World!"
echo ${STR:6:-1}
Run Code Online (Sandbox Code Playgroud)

但是在 OS X(GNU bash,版本 4.3.42(1)-release (x86_64-apple-darwin14.5.0))中,这种用法会产生以下错误:

-1: substring expression < 0
Run Code Online (Sandbox Code Playgroud)

这是 OS X 特定的,还是在以后的 bash 更新中再次被禁用?有没有办法为 OS X 启用此功能?

小智 9

虽然 flabdablet 的解决方案仅适用于固定长度的字符串,但您可以将其用作动态大小字符串的替代品:

echo ${STR:6:$((${#STR} - 6 - 1))}
Run Code Online (Sandbox Code Playgroud)

详细:

  • ${#STR} 返回字符串的长度。
  • $((a - b - c)) 做数学减法
  • ${STR:start:len} 返回一个子字符串。

因此组合子字符串表达式的第二个参数是字符串的长度减去起始偏移量减去您在较新的 bash 语法中指定为负值的值。


小智 2

如果保证 STR 至少包含 7 个字符,则 ${STR:6:${#STR}-7} 应该是 ${STR:6:-1} 的有效替代品。如果它可以更短,这也会导致 OS X bash 抱怨负长度,或者在支持负长度被视为从右偏移量的 bash 版本上出现严重错误。