咱们已经了解了字符串、数组、哈希表、整数、浮点数的基本用法,但应付某些复杂的场景依然力不从心。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。