wiki
  • Introduction
  • Ansible
    • 1 初识Ansible
    • 2 Ansible Inventory 配置详解
    • 3 Ansible Ad-hoc 命令集
    • 3 Ansible lineinfile 模块详解
    • 4 Ansible Playbook
      • 4.1 Playbook的结构及handler用法
      • 4.2 Playbook循环语句
      • 4.3 Playbook条件语句
      • 4.4 Playbook高级用法
      • 4.5 Playbook之tags
      • 4.6 巧用Roles
      • 4.7 文件管理模块及Jinja2过滤器
      • 4.8 yaml 语法
    • 5 Ansible变量
      • 5.1 自定义变量
      • 5.2 Fact变量
      • 5.3 魔法变量
      • 5.4 使用lookup生成变量
      • 5.5 使用vault配置加密
    • 6 Ansible使用优化
  • Linux
    • linux简介
    • 文件管理
      • 查看文件类型
      • 查看文件详细属性
      • 创建、复制、移动、删除
      • 查看文件内容
      • 打包、压缩
    • 文件权限
      • 基本权限UGO
    • 计划任务
    • 用户管理
    • 进程管理
    • 管道及I/O重定向
    • 软件包管理
    • 网络管理
    • 日志logrotate
    • /etc/security/limits.conf 详解与配置
    • 常用知识
  • Shell
    • 第一部分 初见shell
      • 1. 为什么使用shell编程
      • 2. 和Sha-Bang(#!)一起出发
        • 2.1 调用一个脚本
        • 2.2 牛刀小试
    • 第二部分 shell基础
      • 3. 特殊字符
      • 4. 变量与参数
        • 4.1 变量替换
        • 4.2 变量赋值
        • 4.3 Bash弱类型变量
        • 4.4 特殊变量类型
      • 5. 引用
        • 5.1 引用变量
        • 5.2 转义
      • 6. 退出与退出状态
      • 7. 测试
        • 7.1 测试结构
        • 7.2 文件测试操作
        • 7.3 其他比较操作
        • 7.4 嵌套 if/then 条件测试
        • 7.5 牛刀小试
      • 8. 运算符相关话题
        • 8.1 运算符
        • 8.2 数字常量
        • 8.3 双圆括号结构
        • 8.4 运算符优先级
    • 第三部分 shell进阶
      • 9. 换个角度看变量
        • 9.1 内部变量
        • 9.2 变量类型标注:declare 与 typeset
          • 9.2.1 declare 的另类用法
        • 9.3 $RANDOM:生成随机数
      • 10. 变量处理
        • 10.1 字符串处理
          • 10.1.1 使用 awk 处理字符串
          • 10.1.2 参考资料
        • 10.2 参数替换
      • 11. 循环与分支
        • 11.1 循环
        • 11.2 嵌套循环
        • 11.3 循环控制
        • 11.4 测试与分支
      • 12. 命令替换
      • 13. 算术扩展
    • 第四部分 命令
    • 第五部分 高级话题
      • 18.正则表达式
        • 18.1正则表达式简介
        • 18.2文件名替换
        • 18.3 正则表达式对照表
      • 19. 嵌入文档
      • 20. I/O 重定向
        • 20.1 使用 exec
        • 20.2 重定向代码块
        • 20.3 应用程序
      • 21. 子shell
      • 22. 限制模式的Shell
      • 23. 进程替换
      • 24. 函数
        • 24.1 复杂函数和函数复杂性
        • 24.2 局部变量
        • 24.3 不适用局部变量的递归
      • 25. 别名
      • 26. 列表结构
      • 27. 数组
      • 30. 网络编程
      • 33. 选项
      • 34. 陷阱
      • 36. 其他
        • 36.5 有颜色的脚本
        • 36.11 ssh远程操作
    • 第六部分 Google Shell 风格指南
    • 第七部分 实例
  • 3 Python
    • 3.1 简介
    • 3.2 数据类型
    • python subprocess模块的使用
    • python解析nginx配置文件
    • python调用jenkinsAPI批量拷贝视图job
    • python调用zabbixAPI批量添加web监控
    • python监控activemq集群
  • 4 Golang
    • 4.1 程序结构
    • 4.2 数据类型
      • 4.2.1 基础数据类型
      • 4.2.2 复合数据类型
    • 4.3 函数
  • Docker
    • Docker文章推荐
    • Docker Harbor
    • Docker Harbor HA
    • 快速搭建rabbitmq高可用集群
  • Nginx
    • 1.初识Nginx
    • 2.nginx架构基础
    • 3.nginx配置文件详解
      • 3.1 nginx全局块和events块配置
      • 3.2 nginxHTTP块配置
      • 3.3 nginxSERVER块配置
      • 3.4 nginxLOCATION块配置
      • 3.5 nginx常用模块
    • 4.内核参数优化
    • 5.状态码
    • 6.nginx的常见问题
      • Nginx出现403 forbidden的三种原因
  • 8 Tomcat
    • 8.1 tomcat简介
    • 生产环境中的tomcat配置
    • tomcat假死现象
    • Tomcat 错误代号及状态码
    • tomcat注意事项
  • 9 Elasticsearch
    • 9.1 概述
      • 9.1.1 Elasticsearch 简介及其发展历史
      • 9.1.2 Elastic Stack 家族成员及其应用场景
    • 9.2 安装上手
      • 9.2.1 Elasticsearch的安装和简单配置
      • 9.2.2 Kibana的安装和界面快速浏览
      • 9.2.3 在Docker容器中运行Elasticsearch,Kibana和Cerebro
    • 9.3 Elasticsearch入门
      • 9.3.1 基本概念
      • 9.3.2 文档的基本操作CRUP与批量操作
      • 9.3.3 倒排索引入门
      • 9.3.4 通过分析器进行分词
      • 9.3.5 Search API概览
      • 9.3.6 URI Search详解
      • 9.3.7 Request Body和Query DSL简介
  • 10 Zabbix
    • 10.1 zabbix4.4新功能
    • 10.2 zabbix借助ansible安装
    • 10.3 zabbix添加报警媒介
    • 10.4 MySQL监控模块
    • 10.5 Redis监控模块
    • 10.6 常见问题
    • 10.7 用zabbix api批量添加web监控
    • 10.8 activemq监控
    • 10.9 zookeeper集群监控
    • 10.10 Todolist
  • 11 消息中间件
    • 11.1 activemq集群
    • 11.2 rabbitmq
  • 12 常见集群的搭建
    • 12.1 keepalived和heartbeat对比
    • 12.2 zookeeper集群
    • 12.3 fastdfs
    • 12.4 rocketmq集群的搭建
  • 13 常见服务的搭建
    • none
    • 13.2 jdk
    • 13.3 python3.6
    • 13.4 新建博客方法
    • 13.5 confluence
  • 14 Markdown
    • 14.1 让Markdown写作更简单Typora完全使用指南
  • 16 Mysql
    • 16.1 MySQL基本操作
    • 16.2 列表类型和数据完整性
    • 16.3 数据库设计与查询语句
    • 16.4 视图、事务、索引、函数
    • 16.5 MySQL存储引擎
    • 16.6 用户权限和访问控制
    • 16.7 备份恢复
    • 16.8 AB复制
    • 16.9 主主和keepalived
    • 16.10 读写分离和Amoeba
    • 16.11 MySQL逻辑架构
    • 16.12 MySQL锁等待
    • 16.13 MySQL常见问题
    • 16.14 MySQL bin-log日志清理
  • 17 Redis
    • 17.1 安装
    • 17.2 配置
    • 17.3 服务器端和客户端命令
    • 17.4 数据库操作
      • 17.4.1 string类型
      • 17.4.2 键命令
      • 17.4.3 hash类型
      • 17.4.4 list类型
      • 17.4.5 set类型
      • 17.4.6 zset类型
    • 17.5 centos7安装redis-5.0.0主从
    • 17.6 redis5.0.4集群搭建步骤
    • 17.7 centos7安装升级ruby
    • 17.8 redis-dump方式导入导出数据
    • redis面试题
  • 18 HTML
    • 18.1 html入门
  • 19 CSS
    • 19.1 列表、div、span
    • 19.2 整体感知、常见属性、选择器
    • 19.3 css性质、盒模型、标准文档流、浮动
    • 19.4 行高和字号、超链接美化、background
    • 19.5 相对定位、绝对定位、固定定位、z-index
  • 20 jenkins
    • 20.1 jenkins的安装配置
    • 20.2 Jenkins Job迁移
    • Jenkins常见问题
    • Jenkins关闭和重启的实现方式
    • 使用Jenkins Pipeline自动化构建发布
  • 21 vim
    • vim设置参数以方便YAML语句录入
    • vim常用命令
  • 22 网络
    • TCP协议三次握手四次挥手
    • ip地址
  • 23 未分类
    • DEV SIT UAT PET SIM PRD PROD常见环境英文缩写含义
    • 调优
    • 编程语言的分类
    • curl方式执行shell脚本时如何传参
    • 中文技术文档写作规范
    • PrometheusAlert
  • 24 常见问题
    • centos时区
    • curl https报错
    • du-df磁盘使用不一致
    • linux下增加交换分区
    • mysql最大连接数
  • 25 openldap
    • Centos7 搭建openldap
    • phpldapadmin操作指导
  • 26 gitlab
    • gitlab备份迁移升级&集成openldap
  • 27 监控体系
    • 聊头监控体系
    • grafana问题
  • git
    • git的基本使用
    • Commit message 和 Change log 编写指南
Powered by GitBook
On this page
  • 字符串长度
  • $
  • expr length $string
  • expr "$string" : '.*'
  • 起始部分字符串匹配长度
  • expr match "$string" '$substring'
  • expr "$string" : '$substring'
  • 索引
  • expr index $string $substring
  • 截取字符串(字符串分片)
  • ${string:position}
  • ${string:position:length}
  • expr substr $string $position $length
  • expr match "$string" '\($substring\)'
  • expr "$string" : '\($substring\)'
  • expr match "$string" '.*\($substring\)'
  • expr "$string" : '.*\($substring\)'
  • 删除子串
  • ${string#substring}
  • ${string##substring}
  • ${string%substring}
  • ${string%%substring}
  • 子串替换
  • ${string/substring/replacement}
  • ${string//substring/replacement}
  • ${string/#substring/replacement}
  • ${string/%substring/replacement}

Was this helpful?

  1. Shell
  2. 第三部分 shell进阶
  3. 10. 变量处理

10.1 字符串处理

Previous10. 变量处理Next10.1.1 使用 awk 处理字符串

Last updated 5 years ago

Was this helpful?

Bash 支持的字符串操作数量达到了一个惊人的数目。但可惜的是,这些操作工具缺乏一个统一的核心。他们中的一些是的子集,另外一些则是 UNIX 下 函数的子集。这将会导致语法前后不一致或者功能上出现重叠,更不用说那些可能导致的混乱了。

字符串长度

$

expr length $string

上面两个表达式等价于C语言中的 strlen() 函数。

expr "$string" : '.*'

stringZ=abcABC123ABCabc

echo ${#stringZ}                 # 15
echo `expr length $stringz`      # 15
echo `expr "$stringZ" : '.*'`    # 15

样例 10-1. 在文本的段落之间插入空行

#!/bin/bash
# paragraph-space.sh
# 版本 2.1,发布日期 2012年7月29日

# 在无空行的文本文件的段落之间插入空行。
# 像这样使用: $0 <FILENAME

MINLEN=60        # 可以试试修改这个值。它用来做判断。
#  假设一行的字符数小于 $MINLEN,并且以句点结束段落。
#+ 结尾部分有练习!

while read line  # 当文件有许多行的时候
do
  echo "$line"   # 输出行本身。

  len=${#line}
  if [[ "$len" -lt "$MINLEN" && "$line" =~ [*{\.}]$ ]]
# if [[ "$len" -lt "$MINLEN" && "$line" =~ \[*\.\] ]]
# 新版Bash将不能正常运行前一个版本的脚本。Ouch!
# 感谢 Halim Srama 指出这点,并且给出了修正版本。
    then echo    #  在该行以句点结束时,
  fi             #+ 增加一行空行。
done

exit

# 练习:
# -----
#  1) 该脚本通常会在文件的最后插入一个空行。
#+    尝试解决这个问题。
#  2) 在第17行仅仅考虑到了以句点作为句子终止的情况。
#+    修改以满足其他的终止符,例如 ?, ! 和 "。

起始部分字符串匹配长度

expr match "$string" '$substring'

expr "$string" : '$substring'

其中,$substring 是一个正则表达式。

stringZ=abcABC123ABCabc
#       |------|
#       12345678

echo `expr match "$stringZ" 'abc[A-Z]*.2'`   # 8
echo `expr "$stringZ" : 'abc[A-Z]*.2'`       # 8

索引

expr index $string $substring

返回在 $string 中第一个出现的 $substring 字符所在的位置。

stringZ=abcABC123ABCabc
#       123456 ...
echo `expr index "$stringZ" C12`             # 6
                                             # C 的位置。
echo `expr index "$stringZ" 1c`              # 3
# 'c' (第三号位) 较 '1' 出现的更早。

几乎等价于C语言中的 strchr()。

截取字符串(字符串分片)

${string:position}

在 $string 中截取自 $position 起的字符串。

${string:position:length}

在 $string 中截取自 $position 起,长度为 $length 的字符串。

stringZ=abcABC123ABCabc
#       0123456789.....
#       索引位置从0开始。

echo ${stringZ:0}                            # abcABC123ABCabc
echo ${stringZ:1}                            # bcABC123ABCabc
echo ${stringZ:7}                            # 23ABCabc

echo ${stringz:7:3}                          # 23A
                                             # 三个字符的子字符串。



# 从右至左进行截取可行么?

echo ${stringZ:-4}                           # abcABC123ABCabc
# ${parameter:-default} 将会得到整个字符串。
# 但是……

echo ${stringZ:(-4)}                         # Cabc
echo ${stringZ: -4}                          # Cabc
# 现在可以了。
# 括号或者增加空格都可以"转义"位置参数。

# 感谢 Dan Jacobson 指出这些。

其中,参数 position 与 length 可以传入一个变量而不一定需要传入常量。

样例 10-2. 产生一个8个字符的随机字符串

#!/bin/bash
# rand-string.sh
# 产生一个8个字符的随机字符串。

if [ -n "$1" ]  #  如果在命令行中已经传入了参数,
then            #+ 那么就以它作为起始字符串。
  str0="$1"
else            #  否则,就将脚本的进程标识符PID作为起始字符串。
  str0="$$"
fi

POS=2  # 从字符串的第二位开始。
LEN=8  # 截取八个字符。

str1=$( echo "$str0" | md5sum | md5sum )
#                      ^^^^^^   ^^^^^^
# 将字符串通过管道计算两次 md5 来进行两次混淆。

randstring="${str1:$POS:$LEN}"
#                  ^^^^ ^^^^
# 允许传入参数

echo "$randstring"

exit $?

# bozo$ ./rand-string.sh my-password
# 1bdd88c4

# 不过不建议将其作为一种能够抵抗黑客的生成密码的方法。

如果参数 $string 是 "*" 或者 "@",那么将会截取自 $position 起,最大个数为 $length 的位置参数。

echo ${*:2}          # 输出第二个及之后的所有位置参数。
echo ${@:2}          # 同上。

echo ${*:2:3}        # 从第二个位置参数起,输出三个位置参数。

expr substr $string $position $length

在 $string 中截取自 $position 起,长度为 $length 的字符串。

stringZ=abcABC123ABCabc
#       123456789......
#       索引位置从1开始。

echo `expr substr $stringZ 1 2`              # ab
echo `expr substr $stringZ 4 3`              # ABC

expr match "$string" '\($substring\)'

expr "$string" : '\($substring\)'

在 $string 中截取自 $position 起的字符串,其中 $substring 是正则表达式。

stringZ=abcABC123ABCabc
#       =======

echo `expr match "$stringZ" '\(.[b-c]*[A-Z]..[0-9]\)'`   # abcABC1
echo `expr "$stringZ" : '\(.[b-c]*[A-Z]..[0-9]\)'`       # abcABC1
echo `expr "$stringZ" : '\(.......\)'`                   # abcABC1
# 上面所有的形式都给出了相同的结果。

expr match "$string" '.*\($substring\)'

从 $string 结尾部分截取 $substring 字符串,其中 $substring 是正则表达式。

expr "$string" : '.*\($substring\)'

从 $string 结尾部分截取 $substring 字符串,其中 $substring 是正则表达式。

stringZ=abcABC123ABCabc
#                ======

echo `expr match "$stringZ" '.*\([A-C][A-C][A-C][a-c]*\)'`    # ABCabc
echo `expr "$stringZ" : '.*\(......\)'`                       # ABCabc

删除子串

${string#substring}

删除从 $string 起始部分起,匹配到的最短的 $substring。

${string##substring}

删除从 $string 起始部分起,匹配到的最长的 $substring。

stringZ=abcABC123ABCabc
#       |----|          最长
#       |----------|    最短

echo ${stringZ#a*C}      # 123ABCabc
# 删除 'a' 与 'c' 之间最短的匹配。

echo ${stringZ##a*C}     # abc
# 删除 'a' 与 'c' 之间最长的匹配。



# 你可以使用变量代替 substring。

X='a*C'

echo ${stringZ#$X}      # 123ABCabc
echo ${stringZ##$X}     # abc
                        # 同上。

${string%substring}

删除从 $string 结尾部分起,匹配到的最短的 $substring。

例如:

# 将当前目录下所有后缀名为 "TXT" 的文件改为 "txt" 后缀。
# 例如 "file1.TXT" 改为 "file1.txt"。

SUFF=TXT
suff=txt

for i in $(ls *.$SUFF)
do
  mv -f $i $(i%.$SUFF).$suff
  #  除了从变量 $i 右侧匹配到的最短的字符串之外,
  #+ 其他一切都保持不变。
done ### 如果需要,循环可以压缩成一行的形式。

# 感谢 Rory Winston。

${string%%substring}

删除从 $string 结尾部分起,匹配到的最长的 $substring。

stringZ=abcABC123ABCabc
#                    ||     最短
#        |------------|     最长

echo ${stringZ%b*c}      # abcABC123ABCa
# 从结尾处删除 'b' 与 'c' 之间最短的匹配。

echo ${stringZ%%b*c}     # a
# 从结尾处删除 'b' 与 'c' 之间最长的匹配。

这个操作对生成文件名非常有帮助。

样例 10-3. 改变图像文件的格式及文件名

#!/bin/bash
#  cvt.sh:
#  将目录下所有的 MacPaint 文件转换为 "pbm" 格式。

#  使用由 Brian Henderson (bryanh@giraffe-data.com) 维护的
#+ "netpbm" 包下的 "macptobpm" 二进制工具。
#  Netpbm 是大多数 Linux 发行版的标准组成部分。

OPERATION=macptopbm
SUFFIX=pbm          # 新的文件名后缀。

if [ -n "$1" ]
then
  directory=$1      # 如果已经通过脚本参数传入了目录名的情况……
else
  directory=$PWD    # 否则就使用当前工作目录。
fi

#  假设目标目录下的所有 MacPaint 图像文件都拥有
#+ ".mac" 的文件后缀名。

for file in $directory/*    # 文件名匹配。
do
  filename=${file%.*c}      #  从文件名中删除 ".mac" 后缀
                            #+ ('.*c' 匹配 '.' 与 'c' 之间的
                            #  所有字符,包括其本身)。
  $OPERATION $file > "$filename.$SUFFIX"
                            # 将转换结果重定向到新的文件。
  rm -f $file               # 在转换后删除原文件。
  echo "$filename.$SUFFIX"  # 将记录输出到 stdout 中。
done

exit 0

# 练习:
# -----
# 这个脚本会将当前工作目录下的所有文件进行转换。
# 修改脚本,使得它仅转换 ".mac" 后缀的文件。



# *** 还可以使用另外一种方法。 *** #

#!/bin/bash
# 将图像批处理转换成不同的格式。
# 假设已经安装了 imagemagick。(在大部分 Linux 发行版中都有)

INFMT=png   # 可以是 tif, jpg, gif 等等。
OUTFMT=pdf  # 可以是 tif, jpg, gif, pdf 等等。

for pic in *"$INFMT"
do
  p2=$(ls "$pic" | sed -e s/\.$INFMT//)
  # echo $p2
  convert "$pic" $p2.$OUTFMT
done

exit $?

样例 10-4. 将流音频格式转换成 ogg 格式

#!/bin/bash
# ra2ogg.sh: 将流音频文件 (*.ra) 转换成 ogg 格式。

# 使用 "mplayer" 媒体播放器程序:
#      http://www.mplayerhq.hu/homepage
# 使用 "ogg" 库与 "oggenc":
#      http://www.xiph.org/
#
# 脚本同时需要安装一些解码器,例如 sipr.so 等等一些。
# 这些解码器可以在 compat-libstdc++ 包中找到。


OFILEPREF=${1%%ra}      # 删除 "ra" 后缀。
OFILESUFF=wav           # wav 文件后缀。
OUTFILE="$OFILEPREF""$OFILESUFF"
E_NOARGS=85

if [ -z "$1" ]          # 必须指定一个文件进行转换。
then
  echo "Usage: `basename $0` [filename]"
  exit $E_NOAGRS
fi


######################################################
mplayer "$1" -ao pcm:file=$OUTFILE
oggenc "$OUTFILE"  # 由 oggenc 自动加上正确的文件后缀名。
######################################################

rm "$OUTFILE"      # 立即删除 *.wav 文件。
                   # 如果你仍需保留原文件,注释掉上面这一行即可。

exit $?

#  注意:
#  -----
#  在网站上,点击一个 *.ram 的流媒体音频文件
#+ 通常只会下载到 *.ra 音频文件的 URL。
#  你可以使用 "wget" 或者类似的工具下载 *.ra 文件本身。


#  练习:
#  -----
#  这个脚本仅仅转换 *.ra 文件。
#  修改脚本增加适应性,使其可以转换 *.ram 或其他文件格式。
#
#  如果你非常有热情,你可以扩展这个脚本使其
#+ 可以自动下载并且转换流媒体音频文件。
#  给定一个 URL,自动下载流媒体音频文件 (使用 "wget"),
#+ 然后转换它。

样例 10-5. 模拟 getopt

#!/bin/bash
# getopt-simple.sh
# 作者: Chris Morgan
# 允许在高级脚本编程指南中使用。


getopt_simple()
{
    echo "getopt_simple()"
    echo "Parameters are '$*'"
    until [ -z "$1" ]
    do
      echo "Processing parameter of: '$1'"
      if [ ${1:0:1} = '/' ]
      then
          tmp=${1:1}               # 删除开头的 '/'
          parameter=${tmp%%=*}     # 取出名称。
          value=${tmp##*=}         # 取出值。
          echo "Parameter: '$parameter', value: '$value'"
          eval $parameter=$value
      fi
      shift
    done
}

# 将所有参数传递给 getopt_simple()。
getopt_simple $*

echo "test is '$test'"
echo "test2 is '$test2'"

exit 0  # 可以查看该脚本的修改版 UseGetOpt.sh。

---

sh getopt_example.sh /test=value1 /test2=value2

Parameters are '/test=value1 /test2=value2'
Processing parameter of: '/test=value1'
Parameter: 'test', value: 'value1'
Processing parameter of: '/test2=value2'
Parameter: 'test2', value: 'value2'
test is 'value1'
test2 is 'value2'

子串替换

${string/substring/replacement}

替换匹配到的第一个 $substring 为 $replacement。

${string//substring/replacement}

替换匹配到的所有 $substring 为 $replacement。

stringZ=abcABC123ABCabc

echo ${stringZ/abc/xyz}       # xyzABC123ABCabc
                              # 将匹配到的第一个 'abc' 替换为 'xyz'。

echo ${stringZ//abc/xyz}      # xyzABC123ABCxyz
                              # 将匹配到的所有 'abc' 替换为 'xyz'。

echo  ---------------
echo "$stringZ"               # abcABC123ABCabc
echo  ---------------
                              # 字符串本身并不会被修改!

# 匹配以及替换的字符串可以是参数么?
match=abc
repl=000
echo ${stringZ/$match/$repl}  # 000ABC123ABCabc
#              ^      ^         ^^^
echo ${stringZ//$match/$repl} # 000ABC123ABC000
# Yes!          ^      ^        ^^^         ^^^

echo

# 如果没有给定 $replacement 字符串会怎样?
echo ${stringZ/abc}           # ABC123ABCabc
echo ${stringZ//abc}          # ABC123ABC
# 仅仅是将其删除而已。

${string/#substring/replacement}

替换 $string 中最前端匹配到的 $substring 为 $replacement。

${string/%substring/replacement}

替换 $string 中最末端匹配到的 $substring 为 $replacement。

stringZ=abcABC123ABCabc

echo ${stringZ/#abc/XYZ}          # XYZABC123ABCabc
                                  # 将前端的 'abc' 替换为 'XYZ'

echo ${stringZ/%abc/XYZ}          # abcABC123ABCXYZ
                                  # 将末端的 'abc' 替换为 'XYZ'

其中,$substring 是一个。

如果参数 $string 是 "*" 或者 "@",那么将会截取自 $position 起的。

在 $string 中截取自 $position 起的字符串,其中 $substring 是。

下面是使用字符串截取结构对 的一个简单模拟。

参数代换
expr
正则表达式
位置参数
正则表达式
getopt