Linux拓展之Shell变量扩展${}

概述

在 Shell 中 $ 字符可以用于参数扩展,算术扩展和命令替换。可以根据需要使用它来操作和扩展变量,而无需使用 sedawk 等外部命令。



语法

声明变量的语法如下:

# 语法
变量名=变量值
# 示例
msg="hello world"

获取变量值的语法如下:

# 语法一,使用引号引起来是为了避免因为变量中有空格导致出现错误
echo "$变量名"
# 示例一
echo "$msg"

# 语法二,printf 命令也可以输出内容,但不会自动换行,需要通过转义符 \n 进行换行
printf "$变量名"
# 示例
printf "$msg\n"

如果要对变量进行扩展,就可以使用 ${} 语法,格式如下:

# 语法,不进行变量扩展时等价于 "$变量名"
${变量名}
# 示例
echo "${msg}"

在这里插入图片描述



使用

设置默认 Shell 变量值

我们可以为变量设置默认值,语法格式如下:

# 语法
${变量名:-默认值}
${变量名:=默认值}
# 示例
res=${msg:-"hello world"}
res=${msg:="hello world"}

关于它们的使用及区别,详情可参考:Linux拓展之Shell默认变量值

检测变量是否定义

我们可以设置如果变量未定义或者位置参数未传递,则可以用如下语法停止执行脚本,以免报错。命令格式如下:

# 语法
# 如果变量未定义
${变量名?变量未定义输出的提示信息}
# 如果变量未定义或者为空字符串
${变量名:?变量未定义输出的提示信息}
# 未传递位置参数,通常用在脚本或函数中
${位置参数名:?未传递位置参数输出的提示信息}

# 示例
# 如果变量未定义
res=${msg?"变量未定义"}
# 如果变量未定义或者为空字符串
res=${msg:?"变量未定义或为空"}
# 未传递位置参数,通常用在脚本或函数中,$1、$2 等表示接收第 1、2 个参数
res=${1:?"未传递位置参数"}
# 提示信息中也可以使用变量扩展
info="未定义的变量"
res=${msg:?"Error: ${info}."}

在这里插入图片描述

查找字符串长度

如果要查找一个字符串变量的长度,语法格式如下:

# 语法
${
    
    #变量名}

# 示例
msg="hello world"
len=${
    
    #msg}
echo $len

在这里插入图片描述

移除模式

可以移除字符串变量中前面的子串(从前往后)。语法格式如下:

# 语法:可以从变量前面开始移除匹配模式匹配到的所有字符
# 删除匹配模式匹配到的最短部分,非贪婪匹配
${变量名#匹配模式}
# 删除匹配模式匹配到的最长部分,贪婪匹配
${变量名##匹配模式}

# 示例,获取路径所表示的文件后缀
path="/root/src/tar/test.tar.gz"
echo "${path#*.}" # 非贪婪匹配,* 属于通配符,匹配第一个 . 字符前面的所有内容,即会删除第一个 . 字符之前的所有内容,包括 . 字符本身
# 示例,只获取如下路径所表示的文件名
path="/root/src/tar/test.tar.gz"
echo "${path##*/}" # 贪婪匹配,* 属于通配符,匹配最后一个 / 字符前面的所有内容,即会删除最后一个 / 字符之前的所有内容,包括 / 字符本身

在这里插入图片描述

可以移除字符串变量中后面的子串(从后往前)。语法格式如下:

# 语法:可以从变量后面开始移除匹配模式匹配到的所有字符
# 删除匹配模式匹配到的最短部分,非贪婪匹配
${变量名%匹配模式}
# 删除匹配模式匹配到的最长部分,贪婪匹配
${变量名%%匹配模式}

# 示例,获取路径所表示的文件父目录
path="/root/src/tar/test.tar.gz"
echo "${path%/*.tar.gz}" # 非贪婪匹配,* 属于通配符,匹配 /test.tar.gz,会删除该字符串获取到该文件的父目录
# 示例,只获取所表示的文件名而去除掉后缀
file="test.tar.gz"
echo "${file%%.*}" # 贪婪匹配,* 属于通配符,会从后往前找到最后一个 . 字符,然后删除 . 字符及之后的所有字符,留下文件名

在这里插入图片描述

查找和替换

可以查找到旧字符串然后替换成新字符串(可以替代 sed 命令)。语法格式如下:

# 语法,只会替换第一次匹配成功的字符串
${变量名/旧字符串匹配模式/新字符串}
# 语法,替换所有匹配成功的字符串
${变量名//旧字符串匹配模式/新字符串}

# 示例
var="hello world, hello linux."
# 替换变量 var 中的 hello 为 HELLO
out=${var/hello/HELLO}
echo $out
echo $var
# 替换变量 var 中的 world 为 java
out=${var/world/java}
echo $out
echo $var
# 替换变量 var 中的所有 hello 为 HELLO
out=${var//hello/HELLO}
echo $out
echo $var
# 对文件进行重命名
path="/root/test.txt"
cp "${path}" "${path/.txt/.txt.bak}"

在这里插入图片描述

注:会返回修改后的结果,而不是对原变量进行修改。

提取子串

还可以提取子串,表示从 offset 指定的字符开始扩展到参数的最大长度字符。语法格式如下:

# 语法
# 提取从第 offset 个字符开始到字符串结尾的所有字符
${parameter:offset} 
# 提取从第 offset 个字符开始的 length 个字符
${parameter:offset:length} 
${variable:position} 

# 示例1,去除多余的斜线
file="/data.tar.gz"
echo ${file:1}
# 示例2,提取指定个数的字符
name="www.baidu.com"
echo ${name:4:5}

在这里插入图片描述

注:offset 是从字符串的第 1 个字符开始的。

获取匹配的变量名列表

可以获取名称以指定前缀开头的所有变量名称。语法格式如下:

# 语法
${
    
    !指定变量前缀匹配模式}

# 示例
name1="唐僧"
name2="孙悟空"
name3="猪八戒"
echo "${
     
     !name*}"

在这里插入图片描述

转换大小写

可以将字母转换成大写或小写。语法格式如下:

# 语法,将第一个字符转换为大写
${变量名^}
# 语法,将所有字母都转换成大写
${变量名^^}
# 语法,将第一个字符转换为小写
${变量名,}
# 语法,将所有字母都转换成小写
${变量名,,}
# 语法,仅转换第一个字符为小写
${变量名,指定第一个字符}

# 示例,将第一个字符转换为大写
msg="hello"
echo ${msg^}
# 示例,将所有字母都转换成大写
echo ${msg^^}
# 示例,将第一个字符转换为小写
msg="HELLO"
echo ${msg,}
# 示例,将所有字母都转换成小写
echo ${msg,,}
# 示例,仅第一个字符是 H 则转换它
echo ${msg,H}

在这里插入图片描述



总结

所有方便的 bash 参数替换运算符如下表:

语法 说明
${parameter:-defaultValue} 获取默认 shell 变量值
${parameter:=defaultValue} 设置默认 shell 变量值
${parameter:?"Error Message"} 如果未设置参数,则显示错误消息
${#var} 查找字符串的长度
${var%pattern} 从最短的后端(末端)模式中移除
${var%%pattern} 从最长的后端(末端)图案中移除
${var:num1:num2} 子串
${var#pattern} 从最短的正面图案中移除
${var##pattern} 从最长的正面图案中移除
${var/pattern/string} 查找和替换(仅替换第一次出现)
${var//pattern/string} 查找并替换所有匹配项
${!prefix*} 扩展到名称以前缀开头的变量的名称
${var,} 将第一个字符转换为小写。
${var,pattern} 如果匹配成功,才将第一个字符转换为小写。
${var,,} 将所有字符转换为小写。
${var,,pattern} 如果匹配成功,才将所有字符转换为小写。
${var^} 将第一个字符转换为大写。
${var^pattern} 如果匹配成功,才将第一个字符转换为大写。
${var^^} 将所有字符转换为大写。
${var^^pattern} 如果匹配成功,才将所有字符转换为大写。

参考资料:

猜你喜欢

转载自blog.csdn.net/cnds123321/article/details/125212251
今日推荐