[TOC]
除了算术展开,还有一个常见的命令行程序叫做 bc
,能执行更高级别的数学运算。
参数展开
基本参数
最简单的参数展开形式反映在平常使用的变量上。例如:
$a
当 $a 展开后,会变成变量 a 所包含的值。简单参数也可能用花括号引起来:
${a}
# 花括号可以用于把字符串 “_file” 附加到变量 a 的值的后面
echo "${a}_file"
# 通过把数字包裹在花括号中,可以访问大于 9 的位置参数。
${11}
管理空变量的展开
几种用来处理不存在和空变量的参数展开形式。这些展开形式对于解决丢失的位置参数和给参数指定默认值的情况很方便。
语法一:
${parameter:-word}
若 parameter 没有设置(例如,不存在)或者为空,展开结果是 word 的值。若 parameter 不为空,则展开结果是 parameter 的值。语法二:
${parameter:=word}
若 parameter 没有设置或为空,展开结果是 word 的值。另外,word 的值会赋值给 parameter。 若 parameter 不为空,展开结果是 parameter 的值。语法三:
${parameter:?word}
若 parameter 没有设置或为空,这种展开导致脚本带有错误退出,并且 word 的内容会发送到标准错误。若 parameter 不为空,展开结果是 parameter 的值。语法四:
${parameter:+word}
若 parameter 没有设置或为空,展开结果为空。若 parameter 不为空,展开结果是 word 的值会替换掉 parameter 的值;然而,parameter 的值不会改变。
返回变量名的参数展开
shell 具有返回变量名的能力。这会用在一些相当独特的情况下。
# 这种展开会返回以 prefix 开头的已有变量名。
# 根据 bash 文档,这两种展开形式的执行结果相同。
${!prefix*}
${!prefix@}
# 示例:列出所有以 BASH 开头的环境变量名
$ echo ${!BASH*}
BASH BASH_ARGC BASH_ARGV BASH_COMMAND BASH_COMPLETION
BASH_COMPLETION_DIR BASH_LINENO BASH_SOURCE BASH_SUBSHELL
BASH_VERSINFO BASH_VERSION
字符串展开
有大量的展开形式可用于操作字符串。其中许多展开形式尤其适用于路径名的展开。
展开字符串长度
展开成由 parameter 所包含的字符串的长度。通常 parameter 是一个字符串;然而,如果 parameter 是 @ 或者是 * 的话,则展开结果是位置参数的个数。
# 语法
${#parameter}
# 示例
$ foo="This string is long."
$ echo "'$foo' is ${#foo} characters long."
'This string is long.' is 20 characters long.
截取字符串
从 parameter 所包含的字符串中提取一部分字符,提取的字符始于第 offset 个字符(从字符串开头算起)直到字符串的末尾,除非指定提取的长度。
# 语法
${parameter:offset}
${parameter:offset:length}
# 示例
$ foo="This string is long."
$ echo ${foo:5}
string is long.
[me@linuxbox ~]$ echo ${foo:5:6}
string
清除字符串
从 paramter 所包含的字符串中清除开头一部分文本,这些字符要匹配定义的 patten。pattern 是通配符模式,就如那些用在路径名展开中的模式。这两种形式的差异之处是该 # 形式清除最短的匹配结果,而该 ## 模式清除最长的匹配结果。
# 语法
${parameter#pattern}
${parameter##pattern}
# 示例
$ foo=file.txt.zip
$ echo ${foo#*.}
txt.zip
[me@linuxbox ~]$ echo ${foo##*.}
zip
这些展开和上面的 # 和 ## 展开一样,除了它们清除的文本从 parameter 所包含字符串的末尾开始,而不是开头。
# 语法
${parameter%pattern}
${parameter%%pattern}
# 示例
$ foo=file.txt.zip
$ echo ${foo%.*}
file.txt
$ echo ${foo%%.*}
file
查找和替换
这种形式的展开对 parameter 的内容执行查找和替换操作。如果找到了匹配通配符 pattern 的文本, 则用 string 的内容替换它。在正常形式下,只有第一个匹配项会被替换掉。在该 // 形式下,所有的匹配项都会被替换掉。 该 /# 要求匹配项出现在字符串的开头,而 /% 要求匹配项出现在字符串的末尾。/string 可能会省略掉,这样会 导致删除匹配的文本。
# 语法
${parameter/pattern/string}
${parameter//pattern/string}
${parameter/#pattern/string}
${parameter/%pattern/string}
# 示例
$ foo=JPG.JPG
$ echo ${foo/JPG/jpg}
jpg.JPG
$ echo ${foo//JPG/jpg}
jpg.jpg
$ echo ${foo/#JPG/jpg}
jpg.JPG
$ echo ${foo/%JPG/jpg}
JPG.jpg
大小写转换
最新的 bash 版本已经支持字符串的大小写转换了。bash 有四个参数展开和 delare 命令的两个选项来支持大小写转换。
大小写转换的好处:
规范化用户输入。比如说,在试图查询数据库之前,把用户的输入转换标准化。通过把用户输入的字符全部转换成小写字母或大写字母,并且确保数据库中的条目按同样的方式规范化。
declare
把字符串规范成大写或小写字符
#!/bin/bash
# ul-declare: demonstrate case conversion via declare
# 使用 declare 命令创建两个变量,upper 和 lower。
declare -u upper
declare -l lower
if [[ $1 ]]; then
upper="$1"
lower="$1"
echo $upper
echo $lower
fi
# 运行结果
$ ul-declare aBc
ABC
abc
大小写转换参数展开格式 | 结果 |
---|---|
${parameter,,} | 把 parameter 的值全部展开成小写字母。 |
${parameter,} | 仅仅把 parameter 的第一个字符展开成小写字母。 |
${parameter^^} | 把 parameter 的值全部转换成大写字母。 |
${parameter^} | 仅仅把 parameter 的第一个字符转换成大写字母(首字母大写)。 |
示例代码:
#!/bin/bash
# ul-param - demonstrate case conversion via parameter expansion
if [[ $1 ]]; then
echo ${1,,}
echo ${1,}
echo ${1^^}
echo ${1^}
fi
# 运行结果:
$ ul-param aBc
abc
aBc
ABC
ABc
算术求值和展开
算术展开的基本格式:$((expression))
在算术表达式中,shell 支持任意进制的整形常量。
指定不同的数基(进制)表示法 | 描述 |
---|---|
number | 默认情况下,没有任何表示法的数字被看做是十进制数(以 10 为底)。 |
0number | 在算术表达式中,以零开头的数字被认为是八进制数。 |
0xnumber | 十六进制表示法 |
base#number | number 以 base 为底 |
一元运算符
有两个二元运算符,+ 和 -,它们被分别用来表示一个数字是正数还是负数。例如,-5。
简单算术
算术运算符 | 描述 |
---|---|
+ | 加 |
- | 减 |
* | 乘 |
/ | 整除 |
* | 乘方 |
% | 取模(余数) |
赋值运算符
算术表达式可能执行赋值运算。虽然在不同的上下文中,我们已经执行了许多次赋值运算。 每次我们给变量一个值,我们就执行了一次赋值运算。我们也能在算术表达式中执行赋值运算:
$ foo=
$ echo $foo
$ if (( foo = 5 ));then echo "It is true."; fi # 单个 = 运算符执行赋值运算。
It is true.
$ echo $foo
5
赋值运算符表示法 | 描述 |
---|---|
parameter = value | 简单赋值。给 parameter 赋值。 |
parameter += value | 加。等价于 parameter = parameter + value。 |
parameter -= value | 减。等价于 parameter = parameter – value。 |
parameter = value | 乘。等价于 parameter = parameter value。 |
parameter /= value | 整除。等价于 parameter = parameter /value。 |
parameter %= value | 取模。等价于 parameter = parameter % value。 |
parameter++ | 后缀自增变量。等价于 parameter = parameter + 1 (但,要看下面的讨论)。 |
parameter-- | 后缀自减变量。等价于 parameter = parameter - 1。 |
++parameter | 前缀自增变量。等价于 parameter = parameter + 1。 |
--parameter | 前缀自减变量。等价于 parameter = parameter - 1。 |
位运算符
位运算符 | 描述 |
---|---|
~ | 按位取反。对一个数字所有位取反。 |
<< | 位左移。把一个数字的所有位向左移动。 |
>> | 位右移。把一个数字的所有位向右移动。 |
& | 位与。对两个数字的所有位执行一个 AND 操作。 |
| | 位或。对两个数字的所有位执行一个 OR 操作。 |
^ | 位异或。对两个数字的所有位执行一个异或操作。 |
逻辑运算符
比较运算符 | 描述 | |
---|---|---|
<= | 小于或相等 | |
>= | 大于或相等 | |
< | 小于 | |
> | 大于 | |
== | 相等 | |
!= | 不相等 | |
&& | 逻辑与 | |
| | 逻辑或 | |
expr1?expr2:expr3 | 条件(三元)运算符。若表达式 expr1 的计算结果为非零值(算术真),则 执行表 | 达式 expr2,否则执行表达式 expr3。 |
bc — 一种高精度计算器语言
shell 仅仅可以处理所有类型的整形算术,但是 bc 可以执行更高级的数学运算或仅使用浮点数。