Forgetful Alann

In youth we learn, in age we understand.

0%

模式扩展

简介


模式扩展(globbing),Bash 中提供了八种扩展

  • 波浪线扩展
  • ? 字符扩展
  • * 字符扩展
  • 方括号扩展
  • 大括号扩展
  • 变量扩展
  • 子命令扩展
  • 算术扩展

开启/关闭扩展


  • 开启 set -o noglobset -f
  • 关闭 set +o noglobset +f

波浪线扩展


会自动扩展为用户主目录,~user 会扩展为指定用户的主目录

例如:

1
2
3
echo ~
cd ~/.local
echo ~zylyye

字符扩展


字符代表单个字符(不包括空字符)

1
ls abc??.txt

只有文件存在时才会发生扩展,如果没有文件匹配,则会原样输出。

*字符扩展


*匹配任意数量的任意字符,包括零个字符

1
2
ls *.md
echo *.md

类似,如果没有文件匹配,则会原样输出。

* 只匹配当前目录,如需匹配子目录,每个层级都需要一个 *,如 */*/*/*.txt

Bash 4.0 后引入 globstar,可以使用 **匹配零个或多个子目录。例如 **/*.txt

方括号扩展


[abcd] 方括号会匹配括号中的任意字符,这里匹配 a/b/c/d

可以使用 [^...][!...] 来匹配除了括号中的字符

[a-z] 相当于 [abcdef…z]

  • 如需匹配 - 需放在开头或结尾 [-123] 或 [123-]
  • [] 也可放在方括号中

大括号扩展


大括号 {a,b,c}会挨个展开括号中逗号隔开的值,如 {a,b,c}.txt 展开为 a.txt b.txt c.txt。

  • 注意,括号中逗号前后不能有空格,否则会扩展失效
  • 括号可以嵌套 {a,b{1,2},c}
  • 可以使用形如 {a..z} 进行连续扩展,相当于 {a,b,c,d...,z}

可以结合 for 循环使用

1
2
3
4
for i in {0..9}
do
echo $i
done

可以指定扩展的前缀

{01..9} 扩展为 01 02 03 04 …. 09

可以指定步长 {start..end..step}

例如 {0..8..2} 扩展为 0 2 4 6 8

连续多个形成笛卡尔积

{a..c}{1..3} 扩展为 a1 a2 a3 b1 b2 b3 c1 c2 c3

变量扩展


$ 可用来展开变量,获取变量的值,例如 $SHELL 即展开变量 SHELL 的值。

  • 变量也可放在花括号中,例如${SEHLL}
  • 可使用 ${!string*}${!string@}匹配以 string 开头的变量名(注意这里是扩展为变量名,测试在 BASH 中开启)
  • 变量值是另外一个变量名,可以使用 ${!var_name} 扩展

子命令扩展


$(command) 可以扩展命令运行的结果。

  • 比较老的语法:
1
2
3
`command`
# 例如
echo `date`
  • 该语法可以嵌套,例如 $(ls $(pwd))

算术扩展


使用 $((...)) 进行算术运算

例如 echo $((2 + 4))

字符类


[[:class:]] 用来表示某个字符类,可以匹配某一类字符。

  • [[:alnum:]]:匹配任意英文字母与数字
  • [[:alpha:]]:匹配任意英文字母
  • [[:blank:]]:空格和 Tab 键。
  • [[:cntrl:]]:ASCII 码 0-31 的不可打印字符。
  • [[:digit:]]:匹配任意数字 0-9。
  • [[:graph:]]:A-Z、a-z、0-9 和标点符号。
  • [[:lower:]]:匹配任意小写字母 a-z。
  • [[:print:]]:ASCII 码 32-127 的可打印字符。
  • [[:punct:]]:标点符号(除了 A-Z、a-z、0-9 的可打印字符)。
  • [[:space:]]:空格、Tab、LF(10)、VT(11)、FF(12)、CR(13)。
  • [[:upper:]]:匹配任意大写字母 A-Z。
  • [[:xdigit:]]:16进制字符(A-F、a-f、0-9)。

注意事项


  • Bash 会先进行模式扩展,再执行命令
  • 文件名扩展如果没有匹配到文件,扩展会原样输出
  • 多层路径需要手动添加 / ,Bash 4.0 增加 ** 用来匹配零个或多个子路径
  • 创建的文件名中可以包含通配符(需使用单引号包裹)

extglob


可以使用以下命令启用或禁用该特性:

1
2
3
4
5
6
# 查询开启状态
shopt extglob
# 启用
shopt -s extglob
# 禁用
shopt -u extglob

extglob 允许更复杂的模式匹配(其中 pattern-list 是由 | 分隔的模式表达式):

  • ?(pattern-list): 匹配零个或一个模式
  • *(pattern-list): 匹配零个或多个模式
  • +(pattern-list): 匹配一个或多个模式
  • @(pattern-list): 只匹配一个模式
  • !(pattern-list): 匹配指定模式之外的内容

例如:

1
2
3
4
# 匹配零个或一个 def
?(def)
# 匹配一个或多个 .txt 或 .php
+(.txt|.php)

shopt 命令


shopt 命令可以调整 Bash 的特性:

  • 开启 shopt -s [option_name]
  • 关闭 shopt -u [option_name]
  • 查询 shopt [option_name]

option_name:

  • dotglob - 扩展结果包含隐藏文件(以 . 开头的文件)
  • nullglob - 不匹配任何文件时,返回空字符
  • failglob - 不匹配任何文件直接报错
  • extglob - 开启量词语法支持
  • nocaseglob - 通配符扩展不区分大小写
  • globstar - 支持 ** 来匹配零个或多层目录