在 bash 中,通常使用 ${parameter} 表达式来获取 parameter 变量的值,这是一种参数扩展 (parameter expansion)。
Bash 还提供了其他形式的参数扩展,可以对变量值做一些处理,起到操作字符串的效果。例如:

  • ${parameter:offset:length}parameter 变量值的第 offset 个字符开始,获取 length 个字符,得到子字符串。
  • ${#parameter} 获取 parameter 变量值的字符串长度。

注意:这些表达式都不会修改 parameter 自身的变量值,它们只是基于 parameter 变量值扩展得到新的值。
如果要保存这些值,需要赋值给具体的变量。

查看 man bash 的 Parameter Expansion 小节,就能看到相关说明。具体举例说明如下。

${parameter:offset}${parameter:offset:length}

查看 man bash 对 ${parameter:offset}${parameter:offset:length} 的说明如下:

Substring Expansion.
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, 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.

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.

即,${parameter:offset:length} 表达式从 parameter 变量值的第 offset 个字符开始,一直获取 length 个字符,得到一个子字符串,会包括第 offset 个字符自身。

${parameter:offset} 表达式省略了 length 参数,会从 parameter 变量值的第 offset 个字符开始一直获取到末尾。

这里的 lengthoffset 可以是算术表达式。
字符串的 offset 从 0 开始。

如果 offset 的数值小于 0,那么这个值被用作 parameter 变量值的末尾偏移,从后往前获取字符。
如果 length 数值小于 0,它会被当成 parameter 变量值的末尾偏移,而不是当作总的字符数目,且扩展后的结果是在这两个偏移之间的字符。

注意:一个负数的偏移量必须用至少一个空格和冒号分割开,以避免和 :- 扩展产生混淆。
即,这种情况下的冒号 : 和 负号 - 之间至少要有一个空格,类似于 : - 的形式。

具体举例说明如下:

$ value="This is a test string."
$ echo ${value:5}
is a test string.
$ echo ${value:5:2}
is
$ echo ${value:5: -4}
is a test str
$ echo ${value: -7:3}
str
$ echo ${value: -7: -1}
string

可以看到,${value:5} 获取从 value 变量值的第 5 个字符开始,一直到末尾的全部字符。
注意偏移量是从 0 开始,获取到的子字符串包括第 5 个字符自身。

${value:5:2}value 变量值的第 5 个字符开始,获取包括该字符在内的两个字符,也就是 "is" 字符串。

当所给的 length 参数值为负数时,负号和冒号之间要用空格隔开。
此时 length 参数不表示要获取的字符个数,而是表示对应 parameter 变量值从后往前的偏移,而且这个偏移是从 1 开始。
${value:5: -4} 表示从 value 变量值的第 5 个字符开始,一直获取到倒数第 4 个字符为止,不包括倒数第 4 个字符。

当所给的 offset 参数值为负数时,负号和冒号之间要用空格隔开。
此时 offset 参数对应 parameter 变量值从后往前的偏移,而且这个偏移是从 1 开始。
${value: -7:3} 表示从 value 变量值的倒数第 7 个字符串开始,获取包括该字符在内的三个字符,也就是 "str" 字符串。

${value: -7: -1} 表示从 value 变量值的倒数第 7 个字符串开始,一直获取到倒数第 1 个字符为止。
包括倒数第 7 个字符,不包括倒数第 1 个字符。
具体得到的是 "string" 字符串,不包含最后的点号 .

${#parameter}

查看 man bash 对 ${#parameter} 的说明如下:

Parameter length. The length in characters of the value of parameter is substituted.
If parameter is * or @, the value substituted is the number of positional parameters.
If parameter is an array name subscripted by * or @, the value substituted is the number of elements in the array.

即,如果 parameter 变量值是字符串,则 ${#parameter} 可以获取到对应字符串的长度。

具体举例说明如下:

$ value="123456"
$ echo ${#value}
6

注意:在 bash 的参数扩展中,数字属于位置参数(positional parameters),可以用数字来引用传入脚本或者函数的参数。
当用在当前表达式时,就表示获取所传参数的字符串长度。
例如 $1 对应传入的第一个参数,那么 ${#1} 对应所传入第一个参数的字符串长度。
具体举例如下:

$ function param_length() { echo ${#1}; }
$ param_length 123456
6

可以看到,param_length 函数使用 ${#1} 获取到所给第一个参数值的长度。


霜鱼片
446 声望331 粉丝

解读权威文档,编写易懂文章。如有恰好解答您的疑问,多谢赞赏支持~