Bash技巧:使用参数扩展获取变量的子字符串和字符串长度

在 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} 获取到所给第一个参数值的长度。


南木阁
考据党一枚,力求讲述的每个知识点都有出处,有理有据。如能恰好地解答您的疑问,欢迎点赞,谢谢!

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

405 声望
326 粉丝
0 条评论
推荐阅读
Linux技巧:介绍安装完整 man 手册和其他查看姿势
本篇文章介绍在 Linux 中安装完整 man 手册、去掉 man 手册中文版本、和导出 man 手册的方法。安装完整的 man 手册在 Debian 系统、Ubuntu 系统中,可以执行下面命令来安装完整的 man 手册。这会安装系统函数、库...

霜鱼片阅读 6.2k

Bash 常用脚本片段
这段脚本非常有用,你只要在你的脚本开头加上下面的内容,就能以 --param value 的格式解析参数。由于这段脚本尽可能写的短小不占空间,所以格式方面会要求所有的参数都有值,例如不接受无参数的 --daemon,而必...

捏造的信仰5阅读 1.7k评论 1

工具篇:iTerm与Zsh
iTerm2支持许多的主题配色,可以自己定义,也可以参考网上现成的主题配色。我个人比较喜欢draculatheme配色。支持item,vim,phpstorm , 下方存在主题官网路径,按照教程安装即可。

super白4阅读 4.7k

如何使用zx编写shell脚本
在这篇文章中,我们将学习谷歌的zx库提供了什么,以及我们如何使用它来用Node.js编写shell脚本。然后,我们将学习如何通过构建一个命令行工具来使用zx的功能,帮助我们为新的Node.js项目引导配置。

chuck3阅读 1.2k

封面图
深入剖析容器网络和 iptables
Docker 能为我们提供很强大和灵活的网络能力,很大程度上要归功于与 iptables 的结合。在使用时,你可能没有太关注到 iptables 的作用,这是因为 Docker 已经帮我们自动完成了相关的配置。

张晋涛3阅读 1.3k

封面图
麒麟操作系统 (kylinos) 从入门到精通 - 常用软件安装 - 第三篇 常用软件安装(windows下的习惯)
本篇内容大部分从应用商店进行安装,部分通过官网下载,少部分通过命令行安装。1.原生应用1.1钉钉1.2飞书1.3 蓝信1.4 腾讯文档1.5 金山文档1.6 搜狗输入法(拼音)1.7 五笔输入法1.8 libreoffice官方也带了WPS,...

码上世界3阅读 7.5k评论 17

封面图
Metasploit实现木马生成、捆绑及免杀
在一次渗透测试的过程中,避免不了使用到社会工程学的方式来诱骗对方运行我们的木马或者点击我们准备好的恶意链接。木马的捆绑在社会工程学中是我们经常使用的手段,而为了躲避杀毒软件的查杀,我们又不得不对木...

白风之下1阅读 9k

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

405 声望
326 粉丝
宣传栏