咱們已經瞭解了字符串、數組、哈希表、整數、浮點數的基本用法,但應付某些複雜的場景依然力不從心。git
變量修飾語是 zsh 中有一個很獨特的概念,對變量進行操做,功能上和函數相似,但用起來更方便,在一行代碼裏實現複雜功能主要靠它了。而代價是可讀性更差,怎麼用就要本身權衡了。它也是 zsh 最有特點的部分之一。變量修飾語主要應用於數組和哈希表,但也有一小部分能夠應用於字符串(整數和浮點數也會被當成字符串處理)。github
其實前邊的文章中,變量修飾語已經出現過,但當時沒有詳細說明。c#
好比在大小寫轉換的例子中。數組
% str="ABCDE abcde"
# 轉成大寫,(U) 和 :u 兩種用法效果同樣
% echo ${(U)str} --- ${str:u}
ABCDE ABCDE --- ABCDE ABCDE
# 轉成小寫,(L) 和 :l 兩種用法效果同樣
% echo ${(L)str} --- ${str:l}
abcde abcde --- abcde abcde複製代碼
這裏的 (U)
、:l
等等都是變量修飾語。變量修飾語主要有兩種格式。bash
${(x)var}
${var:x}複製代碼
其中 var 是變量名,x 是 一個或多個字母,不一樣字母的功能不一樣。第二行的冒號也多是其餘符號。${var} 和 $var 基本相同,大括號用於避免變量名中的字符和後邊的字符粘連,一般狀況是不須要加大括號的。但若是使用變量修飾語,大括號就必不可少(其實第二種格式中,大括號能夠省略,但考慮可讀性和錯誤提示等因素,仍是加上比較好)。微信
變量修飾語能夠嵌套使用。由於加了修飾語的變量依然是變量,能夠和正常的變量同樣處理。ide
% str=abc
% echo ${(U)str}
ABC
% echo ${(C)${(U)str}}
Abc
% echo ${${a:u}:l}
abc
# 能夠兩種風格嵌套在一塊兒
% echo ${(C)${a:u}}
Abc複製代碼
這裏要注意 $ 以後全程不能有空格,不然會有語法錯誤。也就是說不能經過加空格來避免由於字符擠在一塊兒形成的可讀性變差。但熟悉了格式後,就能夠比較容易識別出代碼的功能。比較複雜的邏輯能夠換行繼續寫,而不必必定嵌套使用。函數
知道了變量修飾語的用法後,重要的就是都有哪些可使用的變量修飾語了。ui
和變量默認值(讀取變量時若是變量爲空或者不存在,使用的默認值)相關的操做,變量能夠是任何類型的。spa
% var=123
# 若是變量有值,就輸出變量值
% echo ${var:-abc}
123
# 若是變量沒有值(變量不存在,爲空字符串、空數組、空哈希表等),輸出 abc
% echo ${varr:-abc}
abc
% var=""
# 和 :- 相似,但只有變量不存在時才替換成默認值
% echo ${var-abc}
% echo ${varr-abc}
abc
% var=""
# 和 :- 相似,但若是變量沒有值,則賦值爲 abc
% echo ${var:=abc}
abc
% echo $var
abc
% var=abc
# 無論 var 有沒有值,都賦值爲 123
% echo ${var::=123}
123
% echo $var
123
% var=""
# 若是 var 沒有值,直接報錯
% echo ${var:?error}
zsh: var: error
% var=abc
# 若是 var 有值,輸出 123
% echo ${var:+123}
% echo ${varr:+123}複製代碼
% array=(aa bb cc dd)
# 用換行符拼接
% echo ${(F)array}
aa
bb
cc
dd
# 用空格拼接
% str=$array
% echo $str
aa bb cc dd
# 使用其餘字符或字符串拼接
% echo ${(j:-=:)array}
aa-=bb-=cc-=dd複製代碼
% str=a##b##c##d
% array=(${(s:##:)str})
% print -l $array
a
b
c
d複製代碼
# 注意若是不加 integer 或者 float,都爲字符串,但計算時會自動轉換類型
% integer i=1
% float f=1.2
% str=abc
% array=(a b c)
% local -A hashmap=(k1 v1 k2 v2)
% echo ${(t)i} ${(t)f} ${(t)str} ${(t)array} ${(t)hashmap}
integer float scalar array association複製代碼
能夠嵌套多層。
% str=abcde
% echo ${${str[3,5]}[3]}
e
% array=(aa bb cc dd)
% echo ${${array[2,3]}[2]}
cc
# 若是隻剩一個元素了,就取字符串的字符
% echo ${${array[2]}[2]}
b
% local -A hashmap=(k1 v1 k2 v2 k3 v3)
% echo ${${hashmap[k1]}[2]}
1複製代碼
不須要再經過繁瑣的 eval 來作這個。
% var=abc
% abc=123
% echo ${(P)var}
123複製代碼
% array=(abc bcde cdefg defghi)
# 只取每一個字符串的最後兩個字符
% echo ${(l:2:)array}
bc de fg hi
# 用空格補全字符串而且右對齊
% print -l ${(l:7:)array}
abc
bcde
cdefg
defghi
# 用指定字符補全
% print -l ${(l:7::0:)array}
0000abc
000bcde
00cdefg
0defghi
# 用指定字符補全,第二個字符只用一次
% print -l ${(l:7::0::1:)array}
0001abc
001bcde
01cdefg
1defghi
# 左對齊
% print -l ${(r:7::0::1:)array}
abc1000
bcde100
cdefg10
defghi1複製代碼
文中只介紹了幾個比較經常使用的變量修飾語,還有一些沒有說起,可能後續再補充。
全系列文章地址:github.com/goreliu/zsh…
付費解決 Windows、Linux、Shell、C、C++、AHK、Python、JavaScript、Lua 等領域相關問題,靈活訂價,歡迎諮詢,微信 ly50247。