3、变量扩展/子串替换
这些结构从ksh中学习而来.
${var:pos}
变量var被展开成从位移pos个字符往后的值.
${var:pos:len}
从变量var中展开成从位移pos的字符往后最长为len的字符串。
${var/Pattern/Replacement}
在变量var第一个匹配Pattern的字符串用Replacement代替.
如果省略了Replacement ,则第一个匹配Pattern的字符串会被删除.
${var//Pattern/Replacement}
全局替换Global replacement.所有在变量var中被Pattern匹配到的都由Replacement代替.
和上面的一样,如果Replacement被省略,则所有的匹配Pattern的字符串都会被删除.
var1=abcd-1234-defg
echo "var1 = $var1"
t=${var1#*-*}
echo "var1 (with everything,up to and including first - stripped out) = $t"
# t=${var1#*-} 也一样,
#+ 因为 # 匹配最短的字符串,
#+ 并且 * 匹配前面所说的所有字符,也包括空字符串.
t=${var1##*-*}
echo "If var1 contains a \"-\",returns empty string... var1 = $t"
t=${var1%*-*}
echo "var1 (with everything from the last - on stripped out) = $t"
echo
# -------------------------------------------------------
path_name=/home/bozo/ideas/thoughts.for.tody
# -------------------------------------------------------
echo "path_name = $path_name"
t=${path_name##/*/}
echo "path_name, stripped of prefixes = $t"
# 在这个特例中,和 t=`basename $path_name` 效果一样.
# t=${path_name%/}; t=${t##*/} 是更一般的解决办法,
#+ 但有时还是会失败.
# 如果$path_name 以一个新行符结尾,那么`basename $path_name` 就>不能正常工作了,
#+ 但上面的表达式可以正常工作.
t=${path_name%/*.*}
# 效果和 t=`dirname $path_name` 一样
echo "path_name, stripped of suffixes = $t"
# 有时这会失败,比如"../", "/foo", # "foo/", "/".
# 移除前缀,特别当basename没有前缀时,
#+ 但目录名可以,但也是问题更复杂了.
echo
t=${path_name:11}
echo "$path_name,with first 11 chars stripped off = $t"
t=${path_name:11:5}
echo "$path_name, with first 11 chars stripped off, length 5 = $t"
echo
t=${path_name/bozo/clown}
echo "$path_name with \"bozo\" replaced by \"clown\" = $t"
t=${path_name/tody/}
echo "$path_name with \"today\" deleted = $t"
t=${path_name//o/O}
echo "$path_name with all o's capitalized = $t"
t=${path_name//o/}
echo "$path_name with all o's deleted = $t"
exit 0
${var/#Pattern/Replacement}
如果变量var的前缀匹配模式Pattern,则用Replacement代替匹配模式的字符串.
${var/%Pattern/Replacement}
如果变量var的后缀匹配模式Pattern,则用Replacement代替匹配模式的字符串.
#!/bin/bash
# var-match.sh:
# Demo of pattern replacement at prefix / suffix of string.
v0=abc1234zip1234abc # 初值.
echo "v0 = $v0" # abc1234zip1234abc
echo
# 匹配字符串的前缀(开头).
v1=${v0/#abc/ABCDEF} # abc1234zip1234abc
echo "v1 = $v1" # ABCDEF1234zip1234abc
# 匹配字符串的后缀(尾部).
v2=${v0/%abc/ABCDEF} # abc1234zip1234abc
echo "v2 = $v2" # abc1234zip1234ABCDEF
echo
# ---------------------------------------------
# 必须匹配字符串的开头/尾部
#+ 否则不会发生替换.
# ---------------------------------------------
v3=${v0/#123/000} # 匹配,但不是在开头
echo "v3 = $v3" # abc1234zip1234abc
# 不会被替换.
v4=${v0/%123/000} # 匹配,但不是尾部.
echo "v4 = $v4" # abc1234zip1234abc
# 不会被替换.
exit 0
${!varprefix*}, ${!varprefix@}
匹配所有前面声明过的变量,并且变量名以varprefix开头.
#!/bin/bash
# prefix.sh
xyz23=whatever
xyz24=
a=${!xyz*} # 展开为声明过的并以“xyz”开头.
echo "a = $a" # a = xyz23 xyz24
a=${!xyz@} # Same as above
echo "a = $a" # a = xyz23 xyz24
# Bash,版本2.04,增加了这个属性.