这篇文章将要介绍方括号及其在命令行中的不同用法。
看完花括号在命令行中的用法之后,现在我们继续来看方括号([]
)在上下文中是如何发挥作用的。
通配
方括号最简单的用法就是通配。你可能在知道“”这个概念之前就已经通过通配来匹配内容了,列出具有相同特征的多个文件就是一个很常见的场景,例如列出所有 JPEG 文件:
1 | ls *.jpg |
使用通配符来得到符合某个模式的所有内容,这个过程就叫通配。
在上面的例子当中,星号(*
)就代表“0 个或多个字符”。除此以外,还有代表“有且仅有一个字符”的问号(?
)。因此
1 | ls d*k* |
可以列出 darkly
和 ducky
,而且 dark
和 duck
也是可以被列出的,因为 *
可以匹配 0 个字符。而
1 | ls d*k? |
则只能列出 ducky
,不会列出 darkly
、dark
和 duck
。
方括号也可以用于通配。为了便于演示,可以创建一个用于测试的目录,并在这个目录下创建文件:
1 | touch file0{0..9}{0..9} |
(如果你还不清楚上面这个命令的原理,可以看一下另一篇介绍花括号的文章)
执行上面这个命令之后,就会创建 file000
、file001
、……、file099
这 100 个文件。
如果要列出这些文件当中第二位数字是 7 或 8 的文件,可以执行:
1 | ls file0[78]? |
如果要列出 file022
、file027
、file028
、file052
、file057
、file058
、file092
、file097
、file098
,可以执行:
1 | ls file0[259][278] |
当然,不仅仅是 ls
,很多其它的命令行工具都可以使用方括号来进行通配操作。但在删除文件、移动文件、复制文件的过程中使用通配,你需要有一点横向思维。
例如将 file010
到 file029
这 30 个文件复制成 archive010
到 archive029
这 30 个副本,不可以这样执行:
1 | cp file0[12]? archive0[12]? |
因为通配只能针对已有的文件,而 archive
开头的文件并不存在,不能进行通配。
而这条命令
1 | cp file0[12]? archive0[1..2][0..9] |
也同样不行,因为 cp
并不允许将多个文件复制到多个文件。在复制多个文件的情况下,只能将多个文件复制到一个指定的目录下:
1 | mkdir archive |
这条命令是可以正常运行的,但它只会把这 30 个文件以同样的名称复制到 archive/
目录下,而这并不是我们想要的效果。
如果你阅读过我关于花括号的文章,你大概会记得可以使用 %
来截掉字符串的末尾部分,而使用 #
则可以截掉字符串的开头部分。
例如:
1 | myvar="Hello World" |
就会输出 Goodbye Cruel World
,因为 #Hello
将 myvar
变量中开头的 Hello
去掉了。
在通配的过程中,也可以使用这一个技巧。
1 | for i in file0[12]?;\ |
上面的第一行命令告诉 Bash 需要对所有 file01
开头或者 file02
开头,且后面只跟一个任意字符的文件进行操作,第二行的 do
和第四行的 done
代表需要对这些文件都执行这一块中的命令。
第三行就是实际的复制操作了,这里使用了两次 $i
变量:第一次在 cp
命令中直接作为源文件的文件名使用,第二次则是截掉文件名开头的 file
部分,然后在开头补上一个 archive
,也就是这样:
1 | "archive" + "file019" - "file" = "archive019" |
最终整个 cp
命令展开为:
1 | cp file019 archive019 |
最后,顺带说明一下反斜杠 \
的作用是将一条长命令拆分成多行,这样可以方便阅读。
在下一节,我们会了解方括号的更多用法,敬请关注。
via: https://www.linux.com/blog/2019/3/using-square-brackets-bash-part-1