18.2. Globbing

Bash 本身无法识别正则表达式。在脚本中,是命令和实用程序(例如 sedawk)来解释正则表达式。

Bash 确实执行文件名扩展 [1] —— 这个过程被称为 globbing —— 但这使用标准的正则表达式集。相反,globbing 识别和扩展 通配符。 Globbing 解释标准通配符 [2] —— *?,方括号中的字符列表,以及某些其他特殊字符(例如 ^ 用于否定匹配的意义)。 然而,在 globbing 中,通配符存在重要的限制。包含以下内容的字符串*将不会匹配以点开头的文件名,例如 .bashrc[3] 同样,?在 globbing 中的含义与作为正则表达式的一部分不同。

bash$ ls -l
total 2
 -rw-rw-r--    1 bozo  bozo         0 Aug  6 18:42 a.1
 -rw-rw-r--    1 bozo  bozo         0 Aug  6 18:42 b.1
 -rw-rw-r--    1 bozo  bozo         0 Aug  6 18:42 c.1
 -rw-rw-r--    1 bozo  bozo       466 Aug  6 17:48 t2.sh
 -rw-rw-r--    1 bozo  bozo       758 Jul 30 09:02 test1.txt

bash$ ls -l t?.sh
-rw-rw-r--    1 bozo  bozo       466 Aug  6 17:48 t2.sh

bash$ ls -l [ab]*
-rw-rw-r--    1 bozo  bozo         0 Aug  6 18:42 a.1
 -rw-rw-r--    1 bozo  bozo         0 Aug  6 18:42 b.1

bash$ ls -l [a-c]*
-rw-rw-r--    1 bozo  bozo         0 Aug  6 18:42 a.1
 -rw-rw-r--    1 bozo  bozo         0 Aug  6 18:42 b.1
 -rw-rw-r--    1 bozo  bozo         0 Aug  6 18:42 c.1

bash$ ls -l [^ab]*
-rw-rw-r--    1 bozo  bozo         0 Aug  6 18:42 c.1
 -rw-rw-r--    1 bozo  bozo       466 Aug  6 17:48 t2.sh
 -rw-rw-r--    1 bozo  bozo       758 Jul 30 09:02 test1.txt

bash$ ls -l {b*,c*,*est*}
-rw-rw-r--    1 bozo  bozo         0 Aug  6 18:42 b.1
 -rw-rw-r--    1 bozo  bozo         0 Aug  6 18:42 c.1
 -rw-rw-r--    1 bozo  bozo       758 Jul 30 09:02 test1.txt
	      

Bash 对未加引号的命令行参数执行文件名扩展。 echo 命令演示了这一点。

bash$ echo *
a.1 b.1 c.1 t2.sh test1.txt

bash$ echo t*
t2.sh test1.txt

bash$ echo t?.sh
t2.sh
	      

Note

可以修改 Bash 解释 globbing 中特殊字符的方式。 set -f 命令禁用 globbing,而nocaseglobnullglob选项 shopt 更改 globbing 行为。

另请参阅 示例 11-5

Caution

包含嵌入式 空格 的文件名可能导致 globbing 失败。 David Wheeler 展示了如何避免许多此类陷阱。

IFS="$(printf '\n\t')"   # Remove space.

#  Correct glob use:
#  Always use for-loop, prefix glob, check if exists file.
for file in ./* ; do         # Use ./* ... NEVER bare *
  if [ -e "$file" ] ; then   # Check whether file exists.
     COMMAND ... "$file" ...
  fi
done

# This example taken from David Wheeler's site, with permission.

Notes

[1]

文件名扩展 意味着扩展包含特殊字符的文件名模式或模板。例如,example.???可能会扩展为example.001和/或example.txt.

[2]

通配符 字符,类似于扑克中的通配符,可以代表(几乎)任何其他字符。

[3]

文件名扩展可以匹配点文件,但前提是模式显式包含点作为文字字符。

~/[.]bashrc    #  Will not expand to ~/.bashrc
~/?bashrc      #  Neither will this.
               #  Wild cards and metacharacters will NOT
               #+ expand to a dot in globbing.

~/.[b]ashrc    #  Will expand to ~/.bashrc
~/.ba?hrc      #  Likewise.
~/.bashr*      #  Likewise.

# Setting the "dotglob" option turns this off.

# Thanks, S.C.