资讯专栏INFORMATION COLUMN

Zsh 开发指南(第八篇 变量修饰语)

Prasanta / 521人阅读

摘要:导读我们已经了解了字符串数组哈希表整数浮点数的基本用法,但应付某些复杂的场景依然力不从心。变量修饰语主要应用于数组和哈希表,但也有一小部分可以应用于字符串整数和浮点数也会被当成字符串处理。

导读

我们已经了解了字符串、数组、哈希表、整数、浮点数的基本用法,但应付某些复杂的场景依然力不从心。

变量修饰语是 zsh 中有一个很独特的概念,对变量进行操作,功能上和函数类似,但用起来更方便,在一行代码里实现复杂功能主要靠它了。而代价是可读性更差,怎么用就要自己权衡了。它也是 zsh 最有特色的部分之一。变量修饰语主要应用于数组和哈希表,但也有一小部分可以应用于字符串(整数和浮点数也会被当成字符串处理)。

变量修饰语的格式

其实前边的文章中,变量修饰语已经出现过,但当时没有详细说明。

比如在大小写转换的例子中。

% 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 等等都是变量修饰语。变量修饰语主要有两种格式。

${(x)var}
${var:x}

其中 var 是变量名,x 是 一个或多个字母,不同字母的功能不同。第二行的冒号也可能是其他符号。${var} 和 $var 基本相同,大括号用于避免变量名中的字符和后边的字符粘连,通常情况是不需要加大括号的。但如果使用变量修饰语,大括号就必不可少(其实第二种格式中,大括号可以省略,但考虑可读性和错误提示等因素,还是加上比较好)。

变量修饰语可以嵌套使用。因为加了修饰语的变量依然是变量,可以和正常的变量一样处理。

% str=abc
% echo ${(U)str}
ABC
% echo ${(C)${(U)str}}
Abc

% echo ${${a:u}:l}
abc

# 可以两种风格嵌套在一起
% echo ${(C)${a:u}}
Abc

这里要注意 $ 之后全程不能有空格,否则会有语法错误。也就是说不能通过加空格来避免因为字符挤在一起造成的可读性变差。但熟悉了格式后,就可以比较容易识别出代码的功能。比较复杂的逻辑可以换行继续写,而没必要一定嵌套使用。

知道了变量修饰语的用法后,重要的就是都有哪些可以使用的变量修饰语了。

变量默认值

和变量默认值(读取变量时如果变量为空或者不存在,使用的默认值)相关的操作,变量可以是任何类型的。

% 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
总结

文中只介绍了几个比较常用的变量修饰语,还有一些没有提及,可能后续再补充。

参考

http://www.bash2zsh.com/zsh_r...

本文不再更新,全系列文章在此更新维护:github.com/goreliu/zshguide

付费解决 Windows、Linux、Shell、C、C++、AHK、Python、JavaScript、Lua 等领域相关问题,灵活定价,欢迎咨询,微信 ly50247。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/10299.html

相关文章

  • Zsh 开发指南(第十九篇 脚本实例讲解)

    摘要:导读本文将讲解一些比较简单的脚本实例。使用哈希表判断是否重复,删除哈希表里已经有的后续文件。思路建一个哈希表存放汉字与数字的对应关系。如果当前运行进程数达到最大进程并发数,则循环检查哈希表里的进程是否退出。 导读 本文将讲解一些比较简单的 zsh 脚本实例。 实例一:复制一个目录的目录结构 功能: 将一个目录及它下边的所有目录复制到另一个目录中(即创建同名目录),但不复制目录下的其他类...

    khlbat 评论0 收藏0
  • Zsh 开发指南(第十八篇 更多内置模块的用法)

    摘要:而且某些时候,我们可能需要操作一个巨大的哈希表,并不能全部将它载入到内存中。是一个很轻量的数据库,可以认为它就像一个保存在文件里的哈希表。的模块用于调度命令的运行。总结本文介绍了几个比较常用的内置模块,以后可能继续补充更多模块的用法。 导读 除了 zsh/mathfunc、zsh/net/socket、zsh/net/tcp,zsh 还内置了一些其他的内置模块。本文简单讲几个比较常用的...

    dkzwm 评论0 收藏0
  • SpringBoot非官方教程 | 八篇:SpringBoot整合mongodb

    摘要:如果你想自定义一些查询,比如根据来查询,获取根据来查询,只需要定义一个方法即可。注意严格按照存入的的字段对应。测试在的应用程序,加入测试代码。启动程序,控制台打印了测试通过。 这篇文章主要介绍springboot如何整合mongodb。 准备工作 安装 MongoDB jdk 1.8 maven 3.0 idea 环境依赖 在pom文件引入spring-boot-starter-da...

    jaysun 评论0 收藏0
  • 一起来学SpringBoot | 八篇:通用Mapper与分页插件的集成

    摘要:通用是为了解决使用中的基本操作,使用它可以很方便的进行开发,可以节省开发人员大量的时间。当该参数设置为时,时会查询第一页,超过总数时,会查询最后一页。 SpringBoot 是为了简化 Spring 应用的创建、运行、调试、部署等一系列问题而诞生的产物,自动装配的特性让我们可以更好的关注业务本身而不是外部的XML配置,我们只需遵循规范,引入相关的依赖就可以轻易的搭建出一个 WEB 工...

    韩冰 评论0 收藏0
  • 【数据结构初阶】八篇——二叉树的链式结构(二叉树的前、中和后序遍历+层序遍历+链式结构的实现+相关

    摘要:代码实现如下二叉树的创建与销毁二叉树的创建问题通过前序遍历的数组给定一串字符串,代表的是空树,其他的都是节点。 ⭐️本篇博客我要来和大家一起聊一聊数据结构中的二...

    BigNerdCoding 评论0 收藏0

发表评论

0条评论

Prasanta

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<