27. 字符串、數(shù)字

[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)值的情況很方便橱鹏。

  1. 語法一:${parameter:-word}
    若 parameter 沒有設(shè)置(例如膜蠢,不存在)或者為空堪藐,展開結(jié)果是 word 的值。若 parameter 不為空挑围,則展開結(jié)果是 parameter 的值礁竞。

  2. 語法二:${parameter:=word}
    若 parameter 沒有設(shè)置或?yàn)榭眨归_結(jié)果是 word 的值杉辙。另外模捂,word 的值會(huì)賦值給 parameter。 若 parameter 不為空蜘矢,展開結(jié)果是 parameter 的值枫绅。

  3. 語法三:${parameter:?word}
    若 parameter 沒有設(shè)置或?yàn)榭眨@種展開導(dǎo)致腳本帶有錯(cuò)誤退出硼端,并且 word 的內(nèi)容會(huì)發(fā)送到標(biāo)準(zhǔn)錯(cuò)誤并淋。若 parameter 不為空,展開結(jié)果是 parameter 的值珍昨。

  4. 語法四:${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ù)贺喝。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市宗兼,隨后出現(xiàn)的幾起案子躏鱼,更是在濱河造成了極大的恐慌,老刑警劉巖殷绍,帶你破解...
    沈念sama閱讀 218,546評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件染苛,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡主到,警方通過查閱死者的電腦和手機(jī)茶行,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,224評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來登钥,“玉大人畔师,你說我怎么就攤上這事∧晾危” “怎么了看锉?”我有些...
    開封第一講書人閱讀 164,911評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長塔鳍。 經(jīng)常有香客問我伯铣,道長,這世上最難降的妖魔是什么轮纫? 我笑而不...
    開封第一講書人閱讀 58,737評(píng)論 1 294
  • 正文 為了忘掉前任腔寡,我火速辦了婚禮,結(jié)果婚禮上掌唾,老公的妹妹穿的比我還像新娘放前。我一直安慰自己,他們只是感情好郑兴,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,753評(píng)論 6 392
  • 文/花漫 我一把揭開白布犀斋。 她就那樣靜靜地躺著,像睡著了一般情连。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上览效,一...
    開封第一講書人閱讀 51,598評(píng)論 1 305
  • 那天却舀,我揣著相機(jī)與錄音虫几,去河邊找鬼。 笑死挽拔,一個(gè)胖子當(dāng)著我的面吹牛辆脸,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播螃诅,決...
    沈念sama閱讀 40,338評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼啡氢,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了术裸?” 一聲冷哼從身側(cè)響起倘是,我...
    開封第一講書人閱讀 39,249評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎袭艺,沒想到半個(gè)月后搀崭,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,696評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡猾编,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,888評(píng)論 3 336
  • 正文 我和宋清朗相戀三年瘤睹,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片答倡。...
    茶點(diǎn)故事閱讀 40,013評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡轰传,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出瘪撇,到底是詐尸還是另有隱情绸吸,我是刑警寧澤,帶...
    沈念sama閱讀 35,731評(píng)論 5 346
  • 正文 年R本政府宣布设江,位于F島的核電站锦茁,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏叉存。R本人自食惡果不足惜码俩,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,348評(píng)論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望歼捏。 院中可真熱鬧稿存,春花似錦、人聲如沸瞳秽。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,929評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽练俐。三九已至袖迎,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背燕锥。 一陣腳步聲響...
    開封第一講書人閱讀 33,048評(píng)論 1 270
  • 我被黑心中介騙來泰國打工辜贵, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人归形。 一個(gè)月前我還...
    沈念sama閱讀 48,203評(píng)論 3 370
  • 正文 我出身青樓托慨,卻偏偏與公主長得像,于是被迫代替她去往敵國和親暇榴。 傳聞我的和親對(duì)象是個(gè)殘疾皇子厚棵,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,960評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容