当前位置: 首页 > news >正文

shell之扩展

Shell脚本中的参数扩展(Parameter Expansion)是一项强大且灵活的功能,它允许你对变量的值进行操作、转换和计算。下面我将为你详细讲解常见的参数扩展用法。

先了解基础

参数扩展的基本形式是 ${parameter},用于获取变量 parameter的值。花括号 {}在多数情况下是可选的,但当变量名后紧接其他字符时,它们能明确界定变量名的范围。

1. 处理默认值和空值

这类扩展用于在变量未设置或为空时提供备选值或执行操作。

  • ${parameter:-word}​:若 parameter未设置或为空,则扩展为 word;否则扩展为 parameter的值。parameter自身的值不会改变

    unset var; echo "Result: ${var:-default}"  # 输出: Result: default
    var="custom"; echo "Result: ${var:-default}" # 输出: Result: custom
    echo "var is still: $var"                   # 输出: var is still: custom
  • ${parameter:=word}​:若 parameter未设置或为空,则将其设置为 word并扩展为 word;否则扩展为 parameter的值。​注意​:不能用于位置参数和特殊参数。

    unset var; echo "Result: ${var:=default}"  # 输出: Result: default
    echo "var is now: $var"                    # 输出: var is now: default
    var="custom"; echo "Result: ${var:=default}" # 输出: Result: custom
  • ${parameter:?word}​:若 parameter未设置或为空,则将 word(或默认错误消息)输出到标准错误​(stderr)并退出脚本;否则扩展为 parameter的值。常用于强制要求提供参数。

    unset var; : ${var:?Error: var is not set} # 输出到stderr: bash: var: Error: var is not set 并退出
    var="ok"; echo "Result: ${var:?Error}"     # 输出: Result: ok
  • ${parameter:+word}​:若 parameter已设置且不为空,则扩展为 word;否则不进行任何替换​(扩展为空)。这类似于一种“条件替换”。

    unset var; echo "Result: ${var:+replaced}"  # 输出: Result: 
    var="value"; echo "Result: ${var:+replaced}" # 输出: Result: replaced
    echo "var remains: $var"                   # 输出: var remains: value

2. 操作字符串:删除与替换

这类扩展用于对变量存储的字符串进行模式匹配和修改。

  • ${parameter#pattern}​:从 parameter值的开头删除与 pattern匹配的最短部分。

    path="/usr/local/bin"; echo "${path#*/}"    # 输出: usr/local/bin (删除最短的`*/`,即第一个`/`及之前)
  • ${parameter##pattern}​:从 parameter值的开头删除与 pattern匹配的最长部分。

    path="/usr/local/bin"; echo "${path##*/}"   # 输出: bin (删除最长的`*/`,即最后一个`/`及之前的所有内容)
  • ${parameter%pattern}​:从 parameter值的末尾删除与 pattern匹配的最短部分。

    file="data.txt.backup"; echo "${file%.*}"   # 输出: data.txt (删除最短的`.*`,即最后一个`.`及之后)
  • ${parameter%%pattern}​:从 parameter值的末尾删除与 pattern匹配的最长部分。

    file="data.txt.backup"; echo "${file%%.*}"  # 输出: data (删除最长的`.*`,即第一个`.`及之后的所有内容)
  • ${parameter/pattern/string}​:将 parameter值中第一个匹配 pattern的子字符串替换为 string

    str="hello world hello"; echo "${str/hello/hi}" # 输出: hi world hello
  • ${parameter//pattern/string}​:将 parameter值中所有匹配 pattern的子字符串替换为 string

    str="hello world hello"; echo "${str//hello/hi}" # 输出: hi world hi
  • ${parameter/#pattern/string}​:如果 pattern匹配 parameter值的开头,则将其替换为 string

    str="hello world"; echo "${str/#hello/hi}"   # 输出: hi world
    str="world hello"; echo "${str/#hello/hi}"   # 输出: world hello (开头不匹配)
  • ${parameter/%pattern/string}​:如果 pattern匹配 parameter值的末尾,则将其替换为 string

    str="file.txt"; echo "${str/%.txt/.doc}"     # 输出: file.doc
    str="file.txt.backup"; echo "${str/%.txt/.doc}" # 输出: file.txt.backup (末尾不是精确匹配.txt)

3. 获取字符串长度和子字符串

  • ${#parameter}​:扩展为 parameter值的字符长度

    str="hello"; echo "Length: ${#str}"          # 输出: Length: 5
  • ${parameter:offset}​:从 parameter值的第 offset个字符开始(0-based)扩展,直到末尾

    str="0123456789"; echo "${str:3}"           # 输出: 3456789
  • ${parameter:offset:length}​:从 parameter值的第 offset个字符开始(0-based),扩展指定长度的字符。

    str="0123456789"; echo "${str:3:4}"          # 输出: 3456

    注意​:offset可为负数,表示从字符串末尾向前计算。负 offset前必须有一个空格,以避免与 :-混淆。

    str="0123456789"; echo "${str: -4:2}"        # 输出: 67 (从倒数第4个字符开始,取2个)

4. 变量转换与间接引用

  • ${parameter@operator}​:对 parameter的值应用特定的 operator

    • Q: 将值转义为可被 Shell 重用的引用形式。

    • E: 对值中的反斜杠转义序列进行扩展(在某些版本的 Bash 中)。

    var="hello 'world'"; echo "${var@Q}"          # 输出: 'hello '\''world'\'''
  • ${!prefix*}或 ${!prefix@}​:扩展为所有以 prefix开头的变量名,由 IFS的第一个字符分隔。

    echo "${!BASH*}" # 可能输出: BASH BASHOPTS BASHPID ... (所有以BASH开头的变量名)
  • ${!name}​:​间接引用。如果 name是一个变量,且它的值是另一个变量的名称,则 ${!name}扩展为那个变量的值。

    foo="bar"; bar="actual value"; echo "${!foo}" # 输出: actual value

5. 修改大小写 (Bash 4.0+)

  • ${parameter^}​:将 parameter值的第一个字符转换为大写。

  • ${parameter^^}​:将 parameter值的所有字符转换为大写。

  • ${parameter,}​:将 parameter值的第一个字符转换为小写。

  • ${parameter,,}​:将 parameter值的所有字符转换为小写。

    word="hello"; echo "${word^}"                # 输出: Hello
    echo "${word^^}"                             # 输出: HELLO
    WORD="HELLO"; echo "${WORD,}"                # 输出: hELLO
    echo "${WORD,,}"                             # 输出: hello

    注意​:^和 ,在某些上下文中也可以用 ~替代。

✨ 实用技巧与注意事项

  1. 保护变量名​:当变量名后紧跟字母、数字或下划线时,使用 {}是必须的,否则 Bash 会将其视为一个整体变量名。

    var="hello"; echo "${var}world"             # 输出: helloworld
    echo "$varworld"                             # 输出: (空,因为变量`varworld`未设置)
  2. 模式匹配​:在 #%##%%///#%中,pattern遵循 Shell 的通配符模式(glob pattern),而不是正则表达式。*匹配任意字符,?匹配单个字符。

  3. 空值与未设置​:对于 ${parameter:-word}${parameter:=word}${parameter:?word}${parameter:+word},​冒号 :的存在至关重要

    • 有冒号​:检查 parameter是 ​未设置​ 还是 ​为空

    • 无冒号​:​仅检查​ parameter是否 ​未设置​(即使设置为空字符串,也算已设置)。

  4. 数组处理​:许多参数扩展形式也可用于数组。例如 ${#array[@]}获取数组元素个数,${array[@]:offset:length}获取子数组。

  5. 引号的重要性​:为了处理包含空格的字符串或文件名,​总是将参数扩展用双引号引起来是一种好习惯。

    file="file with spaces.txt"
    rm $file    # 可能出错,会被视为三个参数
    rm "$file"  # 正确,是一个参数
  6. 性能考虑​:在可能的情况下,使用 Shell 的内置字符串操作(参数扩展)通常比调用外部命令(如 sedawkcut)更高效。

掌握这些参数扩展技巧能极大提升你编写 Shell 脚本的效率和脚本的灵活性。

http://www.dtcms.com/a/362332.html

相关文章:

  • 奇瑞QQ的后轮制动器设计cad+三维图+设计说明书
  • 【Java】谈谈IdentityHashMap
  • 前阿里专家揭秘:你对中国十大GEO专家的认知,99%都是错的
  • 苹果ipa应用安装包ios系统闪退问题
  • 携程旅行网景区,评论数据爬虫项目数据库保存附源码
  • 需求工程——你真的懂吗
  • C 基础(1) - 初识C语言
  • 在Docker容器中运行Windows:Dockur Windows项目全面解析
  • 机器翻译:python库PyGTranslator的详细使用
  • 身份证识别及信息核验 API 对接说明
  • 手写MyBatis第47弹:Interceptor接口设计与Invocation上下文传递机制--MyBatis动态代理生成与方法拦截的精妙实现
  • AI公共数据分析完整实战教程:从原始数据到商业洞察【网络研讨会完整回放】
  • AR-LSAT 推理任务全解析:从逻辑推理到类比推理的挑战
  • 【WIFI电表】物联网无线通讯光伏储能三相单相智能电表
  • 【HarmonyOS】一步解决弹框集成-快速弹框QuickDialog使用详解
  • Hello World背后的秘密:详解 C++ 编译链接模型
  • FPGA|Quartus II 中pll IP核的具体使用方法
  • Redis 的链表:像智能文件夹一样灵活的列表结构
  • 【题解 | 两种做法】洛谷 P4208 [JSOI2008] 最小生成树计数 [矩阵树/枚举]
  • FDTD_梯度波导学习(1)
  • 8.5 循环神经网络的从零开始实现
  • 二维元胞自动机:从生命游戏到自复制系统的计算宇宙
  • AI 安全与伦理:当大模型拥有 “决策能力”,我们该如何建立技术边界与监管框架?
  • Spring Cloud ------ Gateway
  • h5实现内嵌微信小程序支付宝 --截图保存海报分享功能
  • vmware中linux虚拟机提示磁盘空间不足
  • JavaScript 异步编程:Callback、Promise、async/await
  • 知识表示与处理1
  • 【光照】Unity中的[光照模型]概念辨析
  • 精确率、召回率、漏检率、误判率