Bash 的模式扩展

最后更新于:2022-04-02 03:53:04

[TOC] ## 模式扩展 概述 1. Bash 是先进行扩展,再执行命令,命令本身并不存在参数扩展,收到什么参数就原样执行。这一点务必需要记住。 2. 模式扩展早于正则表达式出现,它的功能没有正则那么强大灵活,但是优点是简单和方便 ## `~` 扩展 用户所在目录 ## `?`字符扩展 `?`字符代表文件路径里面的任意单个字符,**除空格** ``` # 存在文件 a.txt、b.txt 和 ab.txt $ ls ?.txt a.txt b.txt $ ls ??.txt ab.txt ``` ## `*`字符扩展 `*`字符代表文件路径里面的任意数量的任意字符,包括零个字符 ``` # 存在文件 a.txt、b.txt 和 ab.txt $ ls *.txt a.txt b.txt ab.txt ``` 输出当前目录的所有文件 ``` ls * ``` `*`只匹配当前目录,不会匹配子目录 ``` # 子目录有一个 a.txt # 无效的写法 $ ls *.txt # 有效的写法 $ ls */*.txt ``` ## 方括号扩展 - 匹配中括号中的字符 如果文件不存在,就会原样输出 ``` # 存在文件 a.txt 和 b.txt $ ls [ab].txt a.txt b.txt # 只存在文件 a.txt $ ls [ab].txt a.txt ``` 如果要匹配 `-` 只能放在最前或是最后 ``` # 存在 aaa、bbb、aba b-b 三个文件 $ ls ?[-b] ? bbb aba b-b ``` ### `[^...]`和`[!...]` 变体 - 排除括号中的字符 ``` # 存在 aaa、bbb、aba 三个文件 $ ls [!a]* bbb ``` ### `[start-end]` 扩展 表示匹配一个连续的范围 `[a-c]`等同于`[abc]`,`[0-9]`匹配`[0123456789]` ``` # 存在文件 report1.txt、report2.txt 和 report3.txt $ ls report[0-9].txt report1.txt report2.txt report3.txt ``` * `[a-z]`:所有小写字母。 * `[a-zA-Z]`:所有小写字母与大写字母。 * `[a-zA-Z0-9]`:所有小写字母、大写字母与数字。 * `[abc]*`:所有以`a`、`b`、`c`字符之一开头的文件名。 * `program.[co]`:文件`program.c`与文件`program.o`。 * `BACKUP.[0-9][0-9][0-9]`:所有以`BACKUP.`开头,后面是三个数字的文件名。 ### 否定形式[!start-end] ``` $ echo report[!1–3].txt report4.txt report5.txt ``` ### 大括号扩展 1. 大括号内部的逗号前后不能有空格 2. 表示分别扩展成大括号里面的所有值 ``` $ echo d{a,e,i,u,o}g dag deg dig dug dog ``` ``` $ ls {a,b,c}.txt ls: 无法访问'a.txt': 没有那个文件或目录 ls: 无法访问'b.txt': 没有那个文件或目录 ls: 无法访问'c.txt': 没有那个文件或目录 ``` > 大括号扩展不是文件名扩展。它会扩展成所有给定的值,而不管是否有对应的文件存在 逗号前面可以没有值,表示扩展的第一项为空。 ``` $ cp a.log{,.bak} # 等同于 # cp a.log a.log.bak ``` ### 大括号嵌套 ``` $ echo {j{p,pe}g,png} jpg jpeg png ``` ### 大括号与中括号区别 ``` # 不存在 a.txt 和 b.txt $ echo [ab].txt [ab].txt $ echo {a,b}.txt a.txt b.txt ``` ## {start..end} 扩展 - 大括号的简写新式 ``` $ echo d{a..d}g dag dbg dcg ddg $ echo Number_{1..5} Number_1 Number_2 Number_3 Number_4 Number_5 ``` 逆序 ``` $ echo {5..1} 5 4 3 2 1 ``` ### 大括号嵌套简写 ``` $ echo .{mp{3..4},m4{a,b,p,v}} .mp3 .mp4 .m4a .m4b .m4p .m4v ``` ### {start..end..step} 设置步长 ``` $ echo {0..8..2} 0 2 4 6 8 ``` ### 多个简写形式连用 ``` $ echo {a..c}-{1..3} a-1 a-2 a-3 b-1 b-2 b-3 c-1 c-2 c-3 ``` ### 实例: 创建目录 新建36个子目录 ``` $ mkdir {2007..2009}-{01..12} drwxr-xr-x. 2 root root 6 Oct 31 14:56 2007-01 drwxr-xr-x. 2 root root 6 Oct 31 14:56 2007-02 ... drwxr-xr-x. 2 root root 6 Oct 31 14:56 2009-11 drwxr-xr-x. 2 root root 6 Oct 31 14:56 2009-12 ``` ### 实例: 控制 `for`循环次数 ``` for i in {1..4} do echo $i done ``` ## 子命令扩展 $(commod) ``` $ echo $(date) Tue Jan 28 00:01:13 CST 2020 //等价于 反引号较老 $ echo `date` Tue Jan 28 00:01:13 CST 2020 ``` ## 算术扩展 ``` $ echo 2+2 2+2 $ echo $((2 + 2)) 4 ``` ## 量词语法 ``` //查看 shopt 是否开启 shopt extglob //开启 shopt -s extglob //关闭 shopt -u extglob ``` 量词语法用来控制模式匹配的次数 * `?(pattern-list)`:匹配零个或一个模式。 * `*(pattern-list)`:匹配零个或多个模式。 * `+(pattern-list)`:匹配一个或多个模式。 * `@(pattern-list)`:只匹配一个模式。 * `!(pattern-list)`:匹配零个或一个以上的模式,但不匹配单独一个的模式。 ``` $ ls abc?(.)txt abctxt abc.txt $ ls abc+(.txt|.php) abc.php abc.txt ``` ## shopt `shopt`命令可以调整 Bash 的行为 ``` # 打开某个参数 $ shopt -s [optionname] # 关闭某个参数 $ shopt -u [optionname] # 查询某个参数关闭还是打开 $ shopt [optionname] ``` ### dotglob 参数 - 扩展结果包括隐藏文件 ``` $ shopt -s dotglob $ ls * abc.txt .config ``` ### nullglob 参数 `nullglob`参数可以让通配符不匹配任何文件名时,返回空字符 ``` $ rm b* rm: 无法删除'b*': 没有那个文件或目录 //开启 $ shopt -s nullglob $ rm b* rm: 缺少操作数 ``` 由于没有`b*`匹配的文件名,所以`rm b*`扩展成了`rm`,导致报错变成了”缺少操作数 ### failglob 参数 `failglob`参数使得通配符不匹配任何文件名时,Bash 会直接报错,而不是让各个命令去处理。 ``` $ shopt -s failglob $ rm b* bash: 无匹配: b* ``` ### nocaseglob 参数 - 让通配符扩展不区分大小写 ``` $ shopt -s nocaseglob $ ls /windows/program* /windows/ProgramData /windows/Program Files /windows/Program Files (x86) ``` ### globstar 参数 开启 `** `匹配 ``` a.txt sub1/b.txt sub1/sub2/c.txt $ shopt -s globstar $ ls **/*.txt a.txt sub1/b.txt sub1/sub2/c.txt ```
';