Linux拓展之Shell变量扩展${}
Posted 二木成林
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Linux拓展之Shell变量扩展${}相关的知识,希望对你有一定的参考价值。
概述
在 Shell 中 $
字符可以用于参数扩展,算术扩展和命令替换。可以根据需要使用它来操作和扩展变量,而无需使用 sed
、awk
等外部命令。
语法
声明变量的语法如下:
# 语法
变量名=变量值
# 示例
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 | 如果匹配成功,才将所有字符转换为大写。 |
参考资料:
以上是关于Linux拓展之Shell变量扩展${}的主要内容,如果未能解决你的问题,请参考以下文章