Shell参数扩展形式学习笔记
文章目录
- Shell参数扩展形式学习笔记
- 空值判断处理 ${parameter:-word} ${parameter:=word} ${parameter:?word} ${parameter:+word}
- 变量位置截取 ${parameter:offset} ${parameter:offset:length}
- 变量匹配组合 ${!prefix*} ${!prefix@} ${!name[@]} ${!name[*]}
- 获取长度 ${#parameter}
- 变量匹配删除 ${parameter#word} ${parameter##word} ${parameter%word} ${parameter%%word}
- 变量文本替换 ${parameter/pattern/string} ${parameter//pattern/string} ${parameter/#pattern/string} ${parameter/%pattern/string}
- 大小写转换 ${parameter^pattern} ${parameter^^pattern} ${parameter,pattern} ${parameter,,pattern}
- 变量特定操作 ${parameter@operator}
在 Bash 的官方文档中,你可以查找关于 Shell 参数扩展的章节,通常位于“3.5.3 Shell Parameter Expansion”章节将提供关于 ${} 语法以及其他参数扩展形式的详细说明和示例。
链接如下:
https://www.gnu.org/software/bash/manual/html_node/Shell-Parameter-Expansion.html
空值判断处理 ${parameter:-word} ${parameter:=word} ${parameter:?word} ${parameter:+word}
举例说明:
这四种 ${}
形式的区别如下:
-
${parameter:-word}
:如果变量parameter
未定义或为空,则使用默认值word
,并将其扩展为该值;否则,保持变量var
的原始值。示例:
var="value" echo "${var:-default}" # 输出 "value" unset var echo "${var:-default}" # 输出 "default"
-
${parameter:=word}
:如果变量parameter
未定义或为空,则将其设置为默认值word
,并将其扩展为该值;否则,保持变量var
的原始值。示例:
var="value" echo "${var:=default}" # 输出 "value" unset var echo "${var:=default}" # 输出 "default"
-
${parameter:?word}
:如果变量parameter
未定义或为空,则输出错误信息word
到标准错误输出,并退出脚本;否则,将变量var
的值扩展为其原始值。示例:
var="value" echo "${var:?Variable var is not set.}" # 输出 "value" unset var echo "${var:?Variable var is not set.}" # 输出错误信息到标准错误输出并退出脚本
-
${parameter:+word}
:如果变量parameter
已经被设置并且不为空,则将其扩展为word
;否则,将其扩展为空字符串。示例:
var="value" echo "${var:+default}" # 输出 "default" unset var echo "${var:+default}" # 输出空字符串
总结:
${parameter:-word}
和${parameter:=word}
用于提供默认值,但前者不会改变变量的值,后者会在变量未定义或为空时设置变量的值。${parameter:?word}
用于检查变量是否已定义,未定义则输出错误信息并退出脚本。${parameter:+word}
用于检查变量是否已设置并且不为空,是则扩展为指定值,否则扩展为空字符串。
变量位置截取 ${parameter:offset} ${parameter:offset:length}
这两种形式都是 Bash 中的参数扩展形式,用于提取字符串的子串。它们的区别在于提取子串的方式:
-
${parameter:offset}
:从变量parameter
的字符串中提取从偏移量offset
开始的子串,直到字符串的末尾。示例:
str="abcdefg" echo "${str:2}" # 输出 "cdefg",从位置 2 开始提取子串
-
${parameter:offset:length}
:从变量parameter
的字符串中提取从偏移量offset
开始,长度为length
的子串。示例:
str="abcdefg" echo "${str:2:3}" # 输出 "cde",从位置 2 开始提取长度为 3 的子串
总结:
${parameter:offset}
提取从偏移量offset
开始到字符串末尾的子串。${parameter:offset:length}
提取从偏移量offset
开始,长度为length
的子串。
变量匹配组合 ${!prefix*} ${!prefix@} ${!name[@]} ${!name[*]}
这四种形式都是 Bash 中的间接引用形式,用于引用以特定前缀开头的变量名。它们的区别在于展开的方式和结果:
-
${!prefix*}
:展开以prefix
开头的所有变量名,并返回由这些变量值组成的字符串列表,每个变量值之间用空格分隔。示例:
var1="value1" var2="value2" echo "${!var*}" # 输出 "var1 var2"
-
${!prefix@}
:与${!prefix*}
类似,展开以prefix
开头的所有变量名,并返回由这些变量值组成的字符串列表,每个变量值之间用空格分隔。示例:
var1="value1" var2="value2" echo "${!var@}" # 输出 "var1 var2"
-
${!name[@]}
:展开数组name
中的所有元素,并返回由这些元素值组成的字符串列表,每个元素值之间用空格分隔。示例:
array=("value1" "value2") echo "${!array[@]}" # 输出 "value1 value2"
-
${!name[*]}
:与${!name[@]}
类似,展开数组name
中的所有元素,并返回由这些元素值组成的单个字符串,元素值之间用第一个字符为IFS
的字符分隔(默认为空格)。示例:
array=("value1" "value2") echo "${!array[*]}" # 输出 "value1 value2"
总结:
${!prefix*}
和${!prefix@}
展开以prefix
开头的所有变量名,并返回由这些变量值组成的字符串列表,每个变量值之间用空格分隔。${!name[@]}
和${!name[*]}
展开数组name
中的所有元素,并返回由这些元素值组成的字符串列表或单个字符串,元素值之间用空格或IFS
分隔。
获取长度 ${#parameter}
${#parameter}
是 Bash 中的参数长度扩展形式,用于获取变量 parameter
的长度。这个形式可以用于获取字符串的长度,也可以用于获取数组的元素个数。
示例:
# 获取字符串的长度
str="Hello, world!"
echo "${#str}" # 输出 "13"# 获取数组的元素个数
array=("apple" "banana" "orange")
echo "${#array[@]}" # 输出 "3"
在第一个示例中,${#str}
返回字符串变量 str
的长度,即 13。
在第二个示例中,${#array[@]}
返回数组变量 array
中元素的个数,即 3。
变量匹配删除 ${parameter#word} ${parameter##word} ${parameter%word} ${parameter%%word}
这四种形式都是 Bash 中的模式删除操作,用于从变量值中删除匹配的部分。它们的区别在于匹配的方式和删除的范围:
-
${parameter#word}
:删除变量parameter
值开头匹配的最短部分(即最短匹配)。示例:
path="/path/to/file.txt" echo "${path#*/}" # 输出 "path/to/file.txt",删除第一个斜杠及其之前的部分
-
${parameter##word}
:删除变量parameter
值开头匹配的最长部分(即最长匹配)。示例:
path="/path/to/file.txt" echo "${path##*/}" # 输出 "file.txt",删除最后一个斜杠及其之前的部分
-
${parameter%word}
:删除变量parameter
值结尾匹配的最短部分(即最短匹配)。示例:
filename="file.txt" echo "${filename%.*}" # 输出 "file",删除最后一个点及其之后的部分
-
${parameter%%word}
:删除变量parameter
值结尾匹配的最长部分(即最长匹配)。示例:
filename="file.txt" echo "${filename%%.*}" # 输出 "file",删除最后一个点及其之后的部分
总结:
${parameter#word}
和${parameter##word}
用于从变量值的开头匹配删除指定部分,区别在于前者是最短匹配,后者是最长匹配。${parameter%word}
和${parameter%%word}
用于从变量值的结尾匹配删除指定部分,区别在于前者是最短匹配,后者是最长匹配。
变量文本替换 ${parameter/pattern/string} ${parameter//pattern/string} ${parameter/#pattern/string} ${parameter/%pattern/string}
这四种形式都是 Bash 中的模式替换操作,用于在变量值中替换匹配的部分。它们的区别在于替换的范围和方式:
-
${parameter/pattern/string}
:将变量parameter
值中第一个匹配的pattern
替换为string
。示例:
text="apple banana banana" echo "${text/ban/orange}" # 输出 "apple orangeana banana",只替换第一个匹配的 "ban"
-
${parameter//pattern/string}
:将变量parameter
值中所有匹配的pattern
替换为string
。示例:
text="apple banana banana" echo "${text//ban/orange}" # 输出 "apple orangeana orangeana",替换所有匹配的 "ban"
-
${parameter/#pattern/string}
:如果变量parameter
值以pattern
开头,则将其替换为string
。示例:
filename="file.txt" echo "${filename/#file/path}" # 输出 "path.txt",替换开头的 "file"
-
${parameter/%pattern/string}
:如果变量parameter
值以pattern
结尾,则将其替换为string
。示例:
filename="file.txt" echo "${filename/%.txt/.csv}" # 输出 "file.csv",替换结尾的 ".txt"
总结:
${parameter/pattern/string}
和${parameter//pattern/string}
用于在变量值中进行模式替换,前者替换第一个匹配,后者替换所有匹配。${parameter/#pattern/string}
和${parameter/%pattern/string}
用于在变量值的开头和结尾匹配替换,分别替换开头和结尾的匹配部分。
大小写转换 ${parameter^pattern} ${parameter^^pattern} ${parameter,pattern} ${parameter,pattern}
这四种形式都是 Bash 中的大小写转换操作,用于将变量值中匹配的部分进行大小写转换。它们的区别在于转换的方式和范围:
-
${parameter^pattern}
:将变量parameter
值中第一个匹配的pattern
转换为大写。示例:
text="hello world" echo "${text^w}" # 输出 "Hello world",将第一个匹配的 "w" 转换为大写
-
${parameter^^pattern}
:将变量parameter
值中所有匹配的pattern
转换为大写。示例:
text="hello world" echo "${text^^o}" # 输出 "hellO wOrld",将所有匹配的 "o" 转换为大写
-
${parameter,pattern}
:将变量parameter
值中第一个匹配的pattern
转换为小写。示例:
text="Hello World" echo "${text,w}" # 输出 "hello World",将第一个匹配的 "W" 转换为小写
-
${parameter,,pattern}
:将变量parameter
值中所有匹配的pattern
转换为小写。示例:
text="Hello World" echo "${text,,o}" # 输出 "hellO WOrld",将所有匹配的 "o" 转换为小写
总结:
${parameter^pattern}
和${parameter^^pattern}
用于将变量值中的匹配部分转换为大写,分别转换第一个匹配和所有匹配。${parameter,pattern}
和${parameter,,pattern}
用于将变量值中的匹配部分转换为小写,分别转换第一个匹配和所有匹配。
变量特定操作 ${parameter@operator}
操作取值:
U 全大写
u 首字母大写
L 全小写
Q 转义字符生成
E 转义字符展开
P 提示符展开
A 变量名和值
K 数组变量名和值
a 属性值
k 数组变量名和值
下面是每个操作的示例:
-
${parameter@U}
:将变量parameter
的值中的所有小写字母转换为大写。示例:
text="hello World" echo "${text@U}" # 输出 "HELLO WORLD"
-
${parameter@u}
:将变量parameter
的值中的第一个字母转换为大写。示例:
text="hello world" echo "${text@u}" # 输出 "Hello world"
-
${parameter@L}
:将变量parameter
的值中的所有大写字母转换为小写。示例:
text="HELLO WORLD" echo "${text@L}" # 输出 "hello world"
-
${parameter@Q}
:返回对变量parameter
的值进行转义后的结果,可以用作输入。示例:
text="Hello World" echo "${text@Q}" # 输出 "Hello\ World"
-
${parameter@E}
:将变量parameter
的值中的反斜杠转义字符展开。示例:
text="Hello\nWorld" echo "${text@E}" # 输出 "Hello World"
-
${parameter@P}
:展开变量parameter
的值,类似于 Bash 提示符展开。示例:
text="Hello World \A" echo "${text@P}" # 输出 "Hello World 14:23"
-
${parameter@A}
:返回一个赋值语句,将重建变量parameter
的属性和值。示例:
text="Hello World" echo "${text@A}" # 输出 "text='Hello World'"
-
${parameter@K}
:返回变量parameter
的值,可能被引号引用,但数组的索引和关联数组的键值对将被逐个展开并用引号引用。示例:
array=("key1" "value1" "key2" "value2") echo "${array@K}" # 输出 "key1='value1' key2='value2'"
-
${parameter@a}
:返回变量parameter
的属性值,表示为一系列标志。示例:
text="Hello World" echo "${text@a}" # 输出 "-"
-:变量既没有被引号引用,也不是数组。
q:变量被单引号引用。
Q:变量被双引号引用。
x:变量是被解释的。
X:变量是被不被解释的。
@:变量是数组或者关联数组。
A:变量是被赋值的(assigned)。