Shell ${} 参数扩展

基本形式

${parameter}

parameter的值替换。

参数扩展

以下的 :,除了 子字符串,表示测试变量是否存在或者 null

如果去掉 :,表示测试是否存在。

${parameter:-word}

如果变量不存在,或者为 null,由word替换,否则 parameter替换。

${parameter:=word}

如果变量不存在,或者为 null,由word替换,否则 parameter替换,并且把word赋值给parameter。脚本参数和特殊参数,可能不会被赋值。

${parameter:?word}

如果变量不存在,或者为 nullword 将被输出到 标准错误,否则 parameter替换。

${parameter:+word}

如果变量不存在,或者为 null,将不会替换,否则由word替换。

$ echo ${a:?a not exists}
bash: a2: a not exists

$ echo ${a:-aaa}
aaa
$ echo $a

# a 没有值,不输出
$ echo ${a:+aaa}

$ echo ${a:=aaa}
aaa
$ echo $a
aaa
# a 有值,输出aaa
$ echo ${a:+aaa}
aaa

${parameter:offset}

${parameter:offset:length}

如果parameter的值为字符串,该表达式为求子字符串。

如果parameter的值为数组,该表达式为求子数组。

如果parameter@,使用脚本的输入参数。这时候,下标从1开始。

如果没有length,将从offset到总结束。

如果没有offset为负数,将从结束往前算offset

如果没有length为负数,结束位置为:从结束往前算length

注意:负的offset前面必须有 空格,以免被识别为 :-扩展。

$ string=01234567890abcdefgh
$ echo ${string:7}
7890abcdefgh
$ echo ${string:7:0}

$ echo ${string:7:2}
78
$ echo ${string:7:-2}
7890abcdef
$ echo ${string: -7}
bcdefgh
$ echo ${string: -7:0}

$ echo ${string: -7:2}
bc
$ echo ${string: -7:-2}
bcdef
$ array=(0 1 2 3 4 5 6 7 8 9 0 a b c d e f g h)
$ echo ${array[@]:7}
7 8 9 0 a b c d e f g h
$ echo ${array[@]:7:2}
7 8
$ echo ${array[@]: -7:2}
b c
$ echo ${array[@]: -7:-2}
bash: -2: substring expression < 0
$ echo ${array[@]:0}
0 1 2 3 4 5 6 7 8 9 0 a b c d e f g h
$ echo ${array[@]:0:2}
0 1
$ echo ${array[@]: -7:0}

${!prefix*}

${!prefix@}

输出所有的 以 prefix 开头的变量,并以 IFS 的第一个值分隔。

$ a="a value"
$ a1=a1
$ a1=11111
$ a2=2222
$ b=bbbb
$ echo ${!a@}
a a1 a2
$ echo ${!a*}
a a1 a2

${!name[@]}

${!name[*]}

输出 数组name的所有下标,如果name不是数组,输出 0

$ a=(v1 v2 v3)
$ echo ${!a[@]}
0 1 2
$ echo ${!a[*]}
0 1 2

${#parameter}

输出 变量 parameter 的长度。

${#@}${#*} 表示位置参数的长度。

如果 parameter 是数组,${#parameter[@]}${#parameter[*]} 表示数组长度。

${parameter#word}

${parameter##word}

word模式匹配 parameter 的值,从开头匹配,并删除。

${parameter#word} 删除最匹配的最短。

${parameter#word} 删除最匹配的最长。

${@#word}${@##word}${*#word}${*##word} 匹配每一个位置参数值,并删除匹配部分。

${array[@]#word}${array[@]##word}${array[*]#word}${array[*]##word} 匹配数组每个成员,并删除匹配部分。

$ a=abcdef
shopt -s extglob
echo ${a##+([a-z])}

bash-3.2$ echo ${a#+([a-z])}
bcdef

${parameter%word}

${parameter%%word}

word模式匹配 parameter 的值,从末尾匹配,并删除。

${parameter%word} 删除最匹配的最短。

${parameter%word} 删除最匹配的最长。

${@%word}${@%%word}${*%word}${*%%word} 匹配每一个位置参数值,并删除匹配部分。

${array[@]%word}${array[@]%%word}${array[*]%word}${array[*]%%word} 匹配数组每个成员,并删除匹配部分。

$ a=abcdef
shopt -s extglob
$ echo ${a%+([a-z])}
abcde
bash-3.2$ echo ${a%%+([a-z])}

${parameter/pattern/string}

pattern模式匹配 parameter 的值,最长匹配,并使用string替换。

一般只替换匹配到的第一个。

pattern/ 开头,替换所有匹配的值。

pattern# 开头,必须开头匹配,并替换。

pattern% 开头,必须结尾匹配,并替换。

${@/pattern/string}${*/pattern/string} 匹配每一个位置参数值,并替换匹配部分。

${array[@]/pattern/string}${array[*]/pattern/string} 匹配数组每一个成员,并替换匹配部分。

$ a='abcd!@$%1234'
shopt -s extglob
$ echo ${a/?([a-z])/.}
.bcd!@$%1234
$ echo ${a/*([a-z])/.}
.!@$%1234

# / 替换所有匹配
$ echo ${a//[a-z]/.}
....!@$%1234
$ echo ${a//[a-z0-9]/.}
....!@$%...


# # 开头匹配
$ echo ${a/#*([a-z])/.}
.!@$%1234
$ echo ${a/#?([a-z])/.}
.bcd!@$%1234

# % 结尾匹配
$ echo ${a/%?([1-9])/.}
abcd!@$%123.
$ echo ${a/%*([1-9])/.}
abcd!@$%.

${parameter^pattern}

${parameter^^pattern}

${parameter,pattern}

${parameter,,pattern}

pattern模式匹配 parameter 的值,并转换大小写。

注意:parameter的每一个字符将使用 pattern 匹配,匹配后转换大小写。 pattern 应该不要匹配多于一个字符的。

  • ^ 小写转大写

  • , 大写转小写

  • ^^ ,, 转换每个匹配到的字符。

  • ^ , 转换匹配到的第一个字符。

如果pattern为空,将使用 ? 匹配每一个字符。

parameter是:${@}${*} 匹配每一个位置参数值,并替换匹配部分。

parameter是: ${array[@]}${array[*]} 匹配数组每一个成员,并替换匹配部分。

a=aBcDe
$ echo ${a^[a-z]}
ABcDe
$ echo ${a,,[a-z]}
abcde
$ echo ${a^^[a-z]}
ABCDE

$ echo ${a,,}
abcde
$ echo ${a^^}
ABCDE

${parameter@operator}

parameter变量的一种转换或者变量的某种信息。具体看 operator 的值。

operator 是一个字符。

  • U

    所有小写字符转大写

  • u

    第一个字符转大写

  • L

    所有大写字符转小写

  • Q

    给变量加上引号,方便后面使用,转义字符保留

      $ foo="one\ntwo\n\tlast"
      $ echo "$foo"
      one\ntwo\n\tlast
    
      $ echo ${foo@Q}
      'one\ntwo\n\tlast'
    
  • E

    执行转义字符串转义。

      $ foo="one\ntwo\n\tlast"
      $ echo "${foo}"
      one\ntwo\n\tlast
    
      $ echo "${foo@E}"
      one
      two
              last
    
  • P

    替换值的 提示符。

      $ bar='host: \h'
      $ echo ${bar@P}
      host: myhost1
    
  • A

    输出声明变量语句

      $ foo="test1"
      $ echo ${foo@A}
      foo='test1'
    
      $ declare -i foo=10
      $ echo "${foo@A}"
      declare -i foo='10'
    
  • K

    尽可能的给变量值加引号,除了使用下标或者key。

  • a

    输出变量的属性

      $ declare -ir foo=10
      $ echo ${foo@a}
      ir
    

    parameter是:${@}${*} 应用在每一个位置参数。

    parameter是: ${array[@]}${array[*]} 应用在数组每一个成员。