5.3 利用 {}
构造参数
在命令行下,我们经常会遇到针对多个参数条目执行操作的使用场景,其中文件名算得上是最常见的情形。为了应对这种情况,bash 和 zsh 都提供了逗号分隔的花括号列表,例如:
将参数传递给 echo
命令之前,Shell 会首先展开花括号列表,并生成以下 3 个参数条目:
利用 {}
(花括号),我们可以实现许多有意思的功能,下面是我常用的几个。大家在学习时不妨举一反三,以便灵活运用。
5.3.1 备份文件
我发现很多朋友在备份文件时执行的命令是:
这条命令将 file
备份为 file.bak
。通过 {}
(花括号),我们可以将该命令改写成:
cp
命令的参数 file{,.bak}
展开后将变成 file file.bak
。这里的 ,
(逗号) 必不可少,否则 Shell 就不会将其展开了。
类似的,我们也可以利用 tar
结合 {}
(花括号) 来创建存档:
这里,tar
命令将 docs
目录存档为 docs.tar
。
5.3.2 生成序列
对于按照一定顺序排列的条目,代替 ,
(逗号),Shell 也支持通过 ..
(两点) 来指定一个区间。比如:
echo
将回显从 a 到 z 所有的小写字母。
又如:
echo
将回显 0 到 9 的数字。
在区间开头数字的前面也可以添加前导的 0,比如:
这将罗列出以下数字序列:
我们甚至还可以在区间的尾端添加一个步进值:
末尾的 2
为步进值,这样就只会罗列奇数:
在 zsh 中,步进值可以为负数,这种情况下将按倒序罗列数字,例如:
bash 中想要达到同样的效果需要将区间的首尾端对调,比如:
最后,让我们来看一个实际使用序列的例子。通过生成的序列,将其与路径组合,在下载多个文件时尤其有用。
上述命令中,wget
将从 https://linuxtoy.org 依次下载 1.png、2.png、3.png … 等图片文件。
值得一提的是,除了 ..
(两点) 的区间表示法,zsh 也支持 -
(减号) 这种区间表示,不过需要启用 braceccl
选项。
xiaodong@codeland:~$ setopt braceccl
xiaodong@codeland:~$ echo {A-Za-z}
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
a b c d e f g h i j k l m n o p q r s t u v w x y z
我们在使用 setopt
开启 braceccl
选项后,执行 echo {A-Za-z}
罗列出了所有大写和小写字母。
5.3.3 连用与嵌套
Shell 的 {}
(花括号) 结构非常灵活和强大,特别是在连用和嵌套时更是威力无穷。先来让我们看一个 {}
(花括号) 连用的例子。
在本例中,我们连用两个 {}
(花括号),这样在每个月份的目录下又分别创建了 baby
和 photo
两个子目录。这条命令实际上执行的是以下命令:
xiaodong@codeland:~$ mkdir -p 2019/01/baby 2019/01/photo \
2019/02/baby 2019/02/photo \
2019/03/baby 2019/03/photo \
2019/04/baby 2019/04/photo \
2019/05/baby 2019/05/photo \
2019/06/baby 2019/06/photo \
2019/07/baby 2019/07/photo \
2019/08/baby 2019/08/photo \
2019/09/baby 2019/09/photo \
2019/10/baby 2019/10/photo \
2019/11/baby 2019/11/photo \
2019/12/baby 2019/12/photo
我们不妨将两个命令比较一下,如果直接手动输入后者该是多么枯燥和乏味的事情。但是,有了 {}
(花括号) 的帮助,我们就变轻松了不少。
{}
(花括号) 结构不仅可以连用,而且能够嵌套。例如:
xiaodong@codeland:~$ echo {{A..Z},{a..z},{0..9}}
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
a b c d e f g h i j k l m n o p q r s t u v w x y z
0 1 2 3 4 5 6 7 8 9
echo
命令的外层 {}
(花括号) 中包含 3 个内层 {}
(花括号),这样就将所有的大写字母、小写字母以及从 0 到 9 的数字都罗列出来了。