ITEEDU

10.3. 变量的操作

10.3.1. 变量算术运算

已经在 第 3.4.6 节 “算术扩展” 讨论过。

10.3.2. 变量的长度

使用 ${#VAR} 语法将计算一个变量当中字符的数量。如果 VAR is “*” or “@”, this value is substituted with the number of positional parameters or number of elements in an array in general. This is demonstrated in the example below:

[bob in ~] echo $SHELL
/bin/bash

[bob in ~] echo ${#SHELL}
9

[bob in ~] ARRAY=(one two three)

[bob in ~] echo ${#ARRAY}
3

10.3.3. 变量的转化

10.3.3.1. 替换

${VAR:-WORD}

如果 VAR 没有定义或者是空值,WORD 的扩展就被替换掉;否则 VAR 的值被替换掉:

[bob in ~] echo ${TEST:-test}
test

[bob in ~] echo $TEST
 

[bob in ~] export TEST=a_string

[bob in ~] echo ${TEST:-test}
a_string

[bob in ~] echo ${TEST2:-$TEST}
a_string

这种形式常常使用在条件测试中,比如在这个里面:

[ -z "${COLUMNS:-}" ] && COLUMNS=80

这是以下形式的简化写法:

if [ -z "${COLUMNS:-}" ]; then
	COLUMNS=80
fi

参见 第 7.1.2.3 节 “字符串比较” 得到更多关于这种类型条件测试的信息。

如果 (-) 使用等号(=)替换, the value is assigned to the parameter if it does not exist:

[bob in ~] echo $TEST2


[bob in ~] echo ${TEST2:=$TEST}
a_string

[bob in ~] echo $TEST2
a_string

以下语法测试一个变量是否存在。如果没有设置,WORD 的扩展打印到标准输出且非交互shell退出。证明:

[bob in ~] cat vartest.sh
#!/bin/bash
 
# This script tests whether a variable is set.  If not,
# it exits printing a message.
 
echo ${TESTVAR:?"There's so much I still wanted to do..."}
echo "TESTVAR is set, we can proceed."

[bob in testdir] ./vartest.sh
./vartest.sh: line 6: TESTVAR: There's so much I still wanted to do...

[bob in testdir] export TESTVAR=present

[bob in testdir] ./vartest.sh
present
TESTVAR is set, we can proceed.

使用 “+” 来替代感叹号instead of the exclamation mark sets the variable to the expansion of WORD; 如果没有设置,什么都不会发生。

10.3.3.2. 去除子字符串Removing substrings

要从一个变量之中,删除等于 OFFSET 数量的字符,使用这样的语法:

${VAR:OFFSET:LENGTH}

LENGTH 参数定义了在偏移点offset之后第一个字符开始需要保留多少字符。如果 LENGTH 省略,就是用剩余的变量的内容。

[bob in ~] export STRING="thisisaverylongname"

[bob in ~] echo ${STRING:4}
isaverylongname

[bob in ~] echo ${STRING:6:5}
avery

${VAR#WORD}

and

${VAR##WORD}

这个结构用来匹配在 VAR 包含 WORDWORD is expanded to produce a pattern just as in file name expansion. If the pattern matches the beginning of the expanded value of VAR, then the result of the expansion is the expanded value of VAR with the shortest matching pattern (“#”) or the longest matching pattern (indicated with “##”).

If VAR is * or @, the pattern removal operation is applied to each positional parameter in turn, and the expansion is the resultant list.

If VAR is an array variable subscribed with “*” or “@”, the pattern removal operation is applied to each member of the array in turn, and the expansion is the resultant list. This is shown in the examples below:

[bob in ~] echo ${ARRAY[*]}
one two one three one four

[bob in ~] echo ${ARRAY[*]#one}
two three four

[bob in ~] echo ${ARRAY[*]#t}
one wo one hree one four

[bob in ~] echo ${ARRAY[*]#t*}
one wo one hree one four

[bob in ~] echo ${ARRAY[*]##t*}
one one one four

The opposite effect is obtained using “%” and “%%”, as in this example below. WORD should match a trailing portion of string:

[bob in ~] echo $STRING
thisisaverylongname

[bob in ~] echo ${STRING%name}
thisisaverylong

10.3.3.3. 替换部分变量的名字

使用

${VAR/PATTERN/STRING}

or

${VAR//PATTERN/STRING}

语法。第一种形式仅仅替换第一个匹配的项目,第二个用 STRING 替换所有匹配 PATTERN 的项目。

[bob in ~] echo ${STRING/name/string}
thisisaverylongstring

更多信息可以在Bash info页面找到。