[TOC]
除了算術(shù)展開异袄,還有一個(gè)常見的命令行程序叫做 bc
通砍,能執(zhí)行更高級(jí)別的數(shù)學(xué)運(yùn)算。
參數(shù)展開
基本參數(shù)
最簡(jiǎn)單的參數(shù)展開形式反映在平常使用的變量上烤蜕。例如:
$a
當(dāng) $a 展開后封孙,會(huì)變成變量 a 所包含的值。簡(jiǎn)單參數(shù)也可能用花括號(hào)引起來:
${a}
# 花括號(hào)可以用于把字符串 “_file” 附加到變量 a 的值的后面
echo "${a}_file"
# 通過把數(shù)字包裹在花括號(hào)中讽营,可以訪問大于 9 的位置參數(shù)虎忌。
${11}
管理空變量的展開
幾種用來處理不存在和空變量的參數(shù)展開形式。這些展開形式對(duì)于解決丟失的位置參數(shù)和給參數(shù)指定默認(rèn)值的情況很方便橱鹏。
語法一:
${parameter:-word}
若 parameter 沒有設(shè)置(例如膜蠢,不存在)或者為空堪藐,展開結(jié)果是 word 的值。若 parameter 不為空挑围,則展開結(jié)果是 parameter 的值礁竞。語法二:
${parameter:=word}
若 parameter 沒有設(shè)置或?yàn)榭眨归_結(jié)果是 word 的值杉辙。另外模捂,word 的值會(huì)賦值給 parameter。 若 parameter 不為空蜘矢,展開結(jié)果是 parameter 的值枫绅。語法三:
${parameter:?word}
若 parameter 沒有設(shè)置或?yàn)榭眨@種展開導(dǎo)致腳本帶有錯(cuò)誤退出硼端,并且 word 的內(nèi)容會(huì)發(fā)送到標(biāo)準(zhǔn)錯(cuò)誤并淋。若 parameter 不為空,展開結(jié)果是 parameter 的值珍昨。語法四:
${parameter:+word}
若 parameter 沒有設(shè)置或?yàn)榭障氐ⅲ归_結(jié)果為空。若 parameter 不為空镣典,展開結(jié)果是 word 的值會(huì)替換掉 parameter 的值兔毙;然而,parameter 的值不會(huì)改變兄春。
返回變量名的參數(shù)展開
shell 具有返回變量名的能力澎剥。這會(huì)用在一些相當(dāng)獨(dú)特的情況下。
# 這種展開會(huì)返回以 prefix 開頭的已有變量名赶舆。
# 根據(jù) bash 文檔哑姚,這兩種展開形式的執(zhí)行結(jié)果相同。
${!prefix*}
${!prefix@}
# 示例:列出所有以 BASH 開頭的環(huán)境變量名
$ 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 是一個(gè)字符串九串;然而绞佩,如果 parameter 是 @ 或者是 * 的話,則展開結(jié)果是位置參數(shù)的個(gè)數(shù)猪钮。
# 語法
${#parameter}
# 示例
$ foo="This string is long."
$ echo "'$foo' is ${#foo} characters long."
'This string is long.' is 20 characters long.
截取字符串
從 parameter 所包含的字符串中提取一部分字符品山,提取的字符始于第 offset 個(gè)字符(從字符串開頭算起)直到字符串的末尾,除非指定提取的長度烤低。
# 語法
${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 是通配符模式拂玻,就如那些用在路徑名展開中的模式酸些。這兩種形式的差異之處是該 # 形式清除最短的匹配結(jié)果宰译,而該 ## 模式清除最長的匹配結(jié)果。
# 語法
${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
查找和替換
這種形式的展開對(duì) parameter 的內(nèi)容執(zhí)行查找和替換操作市栗。如果找到了匹配通配符 pattern 的文本缀拭, 則用 string 的內(nèi)容替換它。在正常形式下填帽,只有第一個(gè)匹配項(xiàng)會(huì)被替換掉蛛淋。在該 // 形式下,所有的匹配項(xiàng)都會(huì)被替換掉篡腌。 該 /# 要求匹配項(xiàng)出現(xiàn)在字符串的開頭褐荷,而 /% 要求匹配項(xiàng)出現(xiàn)在字符串的末尾。/string 可能會(huì)省略掉嘹悼,這樣會(huì) 導(dǎo)致刪除匹配的文本叛甫。
# 語法
${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
大小寫轉(zhuǎn)換
最新的 bash 版本已經(jīng)支持字符串的大小寫轉(zhuǎn)換了。bash 有四個(gè)參數(shù)展開和 delare 命令的兩個(gè)選項(xiàng)來支持大小寫轉(zhuǎn)換杨伙。
大小寫轉(zhuǎn)換的好處:
規(guī)范化用戶輸入其监。比如說,在試圖查詢數(shù)據(jù)庫之前限匣,把用戶的輸入轉(zhuǎn)換標(biāo)準(zhǔn)化抖苦。通過把用戶輸入的字符全部轉(zhuǎn)換成小寫字母或大寫字母,并且確保數(shù)據(jù)庫中的條目按同樣的方式規(guī)范化米死。
declare
把字符串規(guī)范成大寫或小寫字符
#!/bin/bash
# ul-declare: demonstrate case conversion via declare
# 使用 declare 命令創(chuàng)建兩個(gè)變量锌历,upper 和 lower。
declare -u upper
declare -l lower
if [[ $1 ]]; then
upper="$1"
lower="$1"
echo $upper
echo $lower
fi
# 運(yùn)行結(jié)果
$ ul-declare aBc
ABC
abc
大小寫轉(zhuǎn)換參數(shù)展開格式 | 結(jié)果 |
---|---|
${parameter,,} | 把 parameter 的值全部展開成小寫字母哲身。 |
${parameter,} | 僅僅把 parameter 的第一個(gè)字符展開成小寫字母辩涝。 |
${parameter^^} | 把 parameter 的值全部轉(zhuǎn)換成大寫字母贸伐。 |
${parameter^} | 僅僅把 parameter 的第一個(gè)字符轉(zhuǎn)換成大寫字母(首字母大寫)勘天。 |
示例代碼:
#!/bin/bash
# ul-param - demonstrate case conversion via parameter expansion
if [[ $1 ]]; then
echo ${1,,}
echo ${1,}
echo ${1^^}
echo ${1^}
fi
# 運(yùn)行結(jié)果:
$ ul-param aBc
abc
aBc
ABC
ABc
算術(shù)求值和展開
算術(shù)展開的基本格式:$((expression))
在算術(shù)表達(dá)式中,shell 支持任意進(jìn)制的整形常量捉邢。
指定不同的數(shù)基(進(jìn)制)表示法 | 描述 |
---|---|
number | 默認(rèn)情況下脯丝,沒有任何表示法的數(shù)字被看做是十進(jìn)制數(shù)(以 10 為底)。 |
0number | 在算術(shù)表達(dá)式中伏伐,以零開頭的數(shù)字被認(rèn)為是八進(jìn)制數(shù)宠进。 |
0xnumber | 十六進(jìn)制表示法 |
base#number | number 以 base 為底 |
一元運(yùn)算符
有兩個(gè)二元運(yùn)算符,+ 和 -藐翎,它們被分別用來表示一個(gè)數(shù)字是正數(shù)還是負(fù)數(shù)材蹬。例如实幕,-5。
簡(jiǎn)單算術(shù)
算術(shù)運(yùn)算符 | 描述 |
---|---|
+ | 加 |
- | 減 |
* | 乘 |
/ | 整除 |
* | 乘方 |
% | 取模(余數(shù)) |
賦值運(yùn)算符
算術(shù)表達(dá)式可能執(zhí)行賦值運(yùn)算堤器。雖然在不同的上下文中昆庇,我們已經(jīng)執(zhí)行了許多次賦值運(yùn)算。 每次我們給變量一個(gè)值闸溃,我們就執(zhí)行了一次賦值運(yùn)算整吆。我們也能在算術(shù)表達(dá)式中執(zhí)行賦值運(yùn)算:
$ foo=
$ echo $foo
$ if (( foo = 5 ));then echo "It is true."; fi # 單個(gè) = 運(yùn)算符執(zhí)行賦值運(yùn)算。
It is true.
$ echo $foo
5
賦值運(yùn)算符表示法 | 描述 |
---|---|
parameter = value | 簡(jiǎn)單賦值辉川。給 parameter 賦值表蝙。 |
parameter += value | 加。等價(jià)于 parameter = parameter + value乓旗。 |
parameter -= value | 減府蛇。等價(jià)于 parameter = parameter – value。 |
parameter = value | 乘屿愚。等價(jià)于 parameter = parameter value欲诺。 |
parameter /= value | 整除。等價(jià)于 parameter = parameter /value渺鹦。 |
parameter %= value | 取模扰法。等價(jià)于 parameter = parameter % value。 |
parameter++ | 后綴自增變量毅厚。等價(jià)于 parameter = parameter + 1 (但塞颁,要看下面的討論)。 |
parameter-- | 后綴自減變量吸耿。等價(jià)于 parameter = parameter - 1祠锣。 |
++parameter | 前綴自增變量。等價(jià)于 parameter = parameter + 1咽安。 |
--parameter | 前綴自減變量伴网。等價(jià)于 parameter = parameter - 1。 |
位運(yùn)算符
位運(yùn)算符 | 描述 |
---|---|
~ | 按位取反妆棒。對(duì)一個(gè)數(shù)字所有位取反澡腾。 |
<< | 位左移。把一個(gè)數(shù)字的所有位向左移動(dòng)糕珊。 |
>> | 位右移动分。把一個(gè)數(shù)字的所有位向右移動(dòng)。 |
& | 位與红选。對(duì)兩個(gè)數(shù)字的所有位執(zhí)行一個(gè) AND 操作澜公。 |
| | 位或。對(duì)兩個(gè)數(shù)字的所有位執(zhí)行一個(gè) OR 操作喇肋。 |
^ | 位異或坟乾。對(duì)兩個(gè)數(shù)字的所有位執(zhí)行一個(gè)異或操作迹辐。 |
邏輯運(yùn)算符
比較運(yùn)算符 | 描述 | |
---|---|---|
<= | 小于或相等 | |
>= | 大于或相等 | |
< | 小于 | |
> | 大于 | |
== | 相等 | |
!= | 不相等 | |
&& | 邏輯與 | |
| | 邏輯或 | |
expr1?expr2:expr3 | 條件(三元)運(yùn)算符。若表達(dá)式 expr1 的計(jì)算結(jié)果為非零值(算術(shù)真)甚侣,則 執(zhí)行表 | 達(dá)式 expr2右核,否則執(zhí)行表達(dá)式 expr3。 |
bc — 一種高精度計(jì)算器語言
shell 僅僅可以處理所有類型的整形算術(shù)渺绒,但是 bc 可以執(zhí)行更高級(jí)的數(shù)學(xué)運(yùn)算或僅使用浮點(diǎn)數(shù)贺喝。