Shell脚本中的通配符扩展 gaunthan Posted on Jul 12 2016 ? ShellScript ? > 编写shell脚本时,通配符可以用于文件名扩展或用于正则表达式。 ## 文件名扩展(globbing) 文件名扩展中的两个关键字符是问号`?`与星号`*`。问号匹配任意单个字符,星号匹配任意字符序列。因为`*`匹配任意字符序列,所以也可以匹配空字符。而问号不同,它必须总是匹配一个字符。通配符可以位于任意位置。 尽管`?`和`*`是文件名扩展的两个主要元字符,但还有`[...]`这样的结构。可以用它来表示范围,如`[a-z]`指定范围为a~z之间的字母。范围可以任意选择,但`[a-z]`与`[0-9]`使用得最多。另外还有一些定义好的类能用来代替这两个范围,并且意义相同。`[a-z]`等同于`[[:alpha:]]`,`[0-9]`等同于`[[:digit:]]`。全部的可用类如下表: |类|成员| |--|--| |alnum|A-Z、a-z、0-9| |alpha|A-Z、a-z| |blank|空格和制表符| |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|空格、制表符、LF(10)、VT(11)、FF(12)、CR(13)| |upper|A-Z| |xdigit|0-9、A-F、a-f| ### bash的文件名扩展特性 bash指令`set -o noglob`或者`set -f`都可以将文件名扩展功能关闭。`set +o noglob`或`set +f`重新开启。 ### shell选项 shell选项改变shell的工作方式。shell的有些选项会影响到文件名扩展。分别使用命令`shopt -s optionname `与`shopt -u optionname`来设置与取消选项。如果要使用某个shell选项,可以使用`shopt optionname`查询是否设置,或者按照编程的方法使用`shopt -q optionname`。该命令不显示任何输出,但如果选项被设置则返回0,否则返回1。 shell最强大的选项是extglob。整套extglob通配符如下表: |模式|匹配| |--|--| |?(模式列表)|0或1个模式| |*(模式列表)|0或多个模式| |+(模式列表)|1或多个模式列表| |@(模式列表)|1个模式| |!(模式列表)|除了一个模式以外的任何模式| ## 正则表达式和引用 ### 正则表达式概述 正则表达式本身与shell没有直接关系,除了bash的`=~`语法,只有像grep、sed和awk这样的外部工具才使用正则表达式。因为shell扩展与正则表达式使用的语法非常相似,所以从shell传递给外部命令的正则表达式可能会在中途被shell解析。 ### 引用 从shell向外部命令传递参数的方式非常重要。有3种主要形式的引用——单引号、双引号以及反斜线。 ### 单引号 单引号可以防止shell解释其中的内容。shell分析的只是与第一个单引号配对的下一个单引号。单引号中,所有字符按字面意义进行处理,包括双引号。引号自身被忽略,其中的空格将被保留,引号中的变量引用被看成是字符串: ```shell $ hello=hi~ $ echo '$hello world' $hello world ``` ### 双引号 用双引号引用,有部分字符会被shell解释,而不是全部。双引号中,单引号被当成常规字符。其中的变量引用被解释,但文件名不会被扩展,单引号也被保留: ``` $ hello=hi~ $ echo "$hello world.Things '*'" hi~ world.Things '*' ``` ### 反斜线 当需要在常规字符串中包含特殊字符,但它又会被shell解释的时候,可以在字符前加上反斜线`'\'`。可以使用反斜线进行转移的字符有: * 分号`';'`,一般被shell用于在一行内组合多条命令 * 感叹号`'!'`,用于回调历史命令 * `'&'`符号,用于在后台运行进程 * 在花括号扩展中,特殊符号`'{'`、`'}'`和`','`可以通过反斜线转义得到。 * 另外,还可以对命令行中的反斜线本身进行转义`'\\'` 反斜线还能用于续行。一个很长的命令会很难读懂,所以最好选一个位置进行换行。如果一行代码以反斜线结尾,并且紧跟反斜线之后的是换行符,则在解释时反斜线与换行符都会被去掉。 赏 Wechat Pay Alipay 在 Ubuntu Desktop 上启用 SSH Shell脚本中的变量