Section 34.1: 从与字符串匹配的 regex 中获取捕获的组
a='I am a simple string with digits 1234'
pat='(.*) ([0-9]+)'
[[ "$a" =~ $pat ]]
echo "${BASH_REMATCH[0]}"
echo "${BASH_REMATCH[1]}"
echo "${BASH_REMATCH[2]}"
Output:
I am a simple string with digits 1234
I am a simple string with digits
1234
Section 34.2: 当 glob 不匹配任何内容时的行为
准备工作
$ mkdir globbing
$ cd globbing
$ mkdir -p folder/{sub,another}folder/content/deepfolder/
touch macy stacy tracy "file with space" folder/{sub,another}folder/content/deepfolder/file
.hiddenfile
$ shopt -u nullglob
$ shopt -u failglob
$ shopt -u dotglob
$ shopt -u nocaseglob
$ shopt -u extglob
$ shopt -u globstar
如果 glob 没有匹配到任何内容,结果将由 nullglob 和 failglob 选项决定。如果这两个选项都没有设置,那么如果没有匹配到任何内容,Bash 将返回 glob 本身
$ echo no*match
no*match
如果激活了 nullglob,则不会返回任何内容(空):
$ shopt -s nullglob
$ echo no*match
$
如果激活 failglob,则会返回错误信息:
$ shopt -s failglob
$ echo no*match
bash: no match: no*match
$
请注意,failglob 选项优先于 nullglob 选项,也就是说,如果同时设置了 nullglob 和 failglob,那么在不匹配的情况下,将返回错误信息。
Section 34.3: 检查字符串是否与正则表达式匹配
Version ≥ 3.0
Check if a string consists in exactly 8 digits:
$ date=20150624
$ [[ $date =~ ^[0-9]{8}$ ]] && echo "yes" || echo "no"
yes
$ date=hello
$ [[ $date =~ ^[0-9]{8}$ ]] && echo "yes" || echo "no"
no
Section 34.4: regex 匹配
pat='[^0-9]+([0-9]+)'
s='I am a string with some digits 1024'
[[ $s =~ $pat ]] # $pat must be unquoted
echo "${BASH_REMATCH[0]}"
echo "${BASH_REMATCH[1]}"
Output:
I am a string with some digits 1024
1024
我们也可以这样做,而不是将 regex 赋值给变量 ($pat):
[[ $s =~ [^0-9]+([0-9]+) ]]
-
说明
-
[[$s=~$pat]]结构执行 regex 匹配 -
捕获的分组(即匹配结果)在名为
BASH_REMATCH的数组中可用 -
BASH_REMATCH数组中的第 0 个索引是总匹配结果 -
BASH_REMATCH数组中的第 i 个索引是第 i 个捕获组,其中 i = 1、2、3 ...
Section 34.5: The * glob
准备工作
$ mkdir globbing
$ cd globbing
$ mkdir -p folder/{sub,another}folder/content/deepfolder/
touch macy stacy tracy "file with space" folder/{sub,another}folder/content/deepfolder/file
.hiddenfile
$ shopt -u nullglob
$ shopt -u failglob
$ shopt -u dotglob
$ shopt -u nocaseglob
$ shopt -u extglob
$ shopt -u globstar
星号 * 可能是最常用的 glob。它可以简单地匹配任何字符串
$ echo *acy
macy stacy tracy
单个 * 不会匹配子文件夹中的文件和文件夹
$ echo *
emptyfolder folder macy stacy tracy
$ echo folder/*
folder/anotherfolder folder/subfolder
Section 34.6: The ** glob
Version ≥ 4.0
准备工作
$ mkdir globbing
$ cd globbing
$ mkdir -p folder/{sub,another}folder/content/deepfolder/
touch macy stacy tracy "file with space" folder/{sub,another}folder/content/deepfolder/file
.hiddenfile
$ shopt -u nullglob
$ shopt -u failglob
$ shopt -u dotglob
$ shopt -u nocaseglob
$ shopt -u extglob
$ shopt -s globstar
Bash 可以将两个相邻的星号解释为一个 glob。激活 globstar 选项后,可以用来匹配目录结构中更深的文件夹
echo **
emptyfolder folder folder/anotherfolder folder/anotherfolder/content
folder/anotherfolder/content/deepfolder folder/anotherfolder/content/deepfolder/file
folder/subfolder folder/subfolder/content folder/subfolder/content/deepfolder
folder/subfolder/content/deepfolder/file macy stacy tracy
可以把 ** 视为路径扩展,无论路径有多深。本例匹配任何以 deep 开头的文件或文件夹,无论其嵌套多深:
$ echo **/deep*
folder/anotherfolder/content/deepfolder folder/subfolder/content/deepfolder
Section 34.7: The ? glob
准备工作
$ mkdir globbing
$ cd globbing
$ mkdir -p folder/{sub,another}folder/content/deepfolder/
touch macy stacy tracy "file with space" folder/{sub,another}folder/content/deepfolder/file
.hiddenfile
$ shopt -u nullglob
$ shopt -u failglob
$ shopt -u dotglob
$ shopt -u nocaseglob
$ shopt -u extglob
$ shopt -u globstar
? 只需匹配一个字符即可
$ echo ?acy
macy
$ echo ??acy
stacy tracy
Section 34.8: The [ ] glob
准备工作
$ mkdir globbing
$ cd globbing
$ mkdir -p folder/{sub,another}folder/content/deepfolder/
touch macy stacy tracy "file with space" folder/{sub,another}folder/content/deepfolder/file
.hiddenfile
$ shopt -u nullglob
$ shopt -u failglob
$ shopt -u dotglob
$ shopt -u nocaseglob
$ shopt -u extglob
$ shopt -u globstar
如果需要匹配特定字符,则可以使用[]。[]内的任何字符都将精确匹配一次。
$ echo [m]acy
macy
$ echo [st][tr]acy
stacy tracy
然而,[] glob 的功能远不止于此。它还允许负匹配,甚至匹配字符范围和字符类别。使用 ! 或 ^ 作为 [ 后的第一个字符,就可以实现负匹配。我们可以通过以下方式匹配 stacy
$ echo [!t][^r]acy
stacy
在这里,我们要告诉 bash,只匹配不以 t 开头、第二个字母不是 r 且以 acy 结尾的文件。
用连字符 (-) 分隔一对字符可以匹配范围。介于这两个字符之间的任何字符(包括在内)都将被匹配。例如,[r-t]等同于[rst]。
$ echo [r-t][r-t]acy
stacy tracy
字符类可以用 [:class:] 匹配,例如,为了匹配包含空格的文件
$ echo *[[:blank:]]*
file with space
Section 34.9: 匹配隐藏文件
准备工作
$ mkdir globbing
$ cd globbing
$ mkdir -p folder/{sub,another}folder/content/deepfolder/
touch macy stacy tracy "file with space" folder/{sub,another}folder/content/deepfolder/file
.hiddenfile
$ shopt -u nullglob
$ shopt -u failglob
$ shopt -u dotglob
$ shopt -u nocaseglob
$ shopt -u extglob
$ shopt -u globstar
Bash 内置选项 dotglob 允许匹配隐藏的文件和文件夹,即以 .开头的文件和文件夹。
$ shopt -s dotglob
$ echo *
file with space folder .hiddenfile macy stacy tracy
Section 34.10: 不区分大小写匹配
准备工作
$ mkdir globbing
$ cd globbing
$ mkdir -p folder/{sub,another}folder/content/deepfolder/
touch macy stacy tracy "file with space" folder/{sub,another}folder/content/deepfolder/file
.hiddenfile
$ shopt -u nullglob
$ shopt -u failglob
$ shopt -u dotglob
$ shopt -u nocaseglob
$ shopt -u extglob
$ shopt -u globstar
设置 nocaseglob 选项将以不区分大小写的方式匹配 glob
$ echo M*
M*
$ shopt -s nocaseglob
$ echo M*
macy
Section 34.11: 扩展 globbing
Version ≥ 2.02
准备工作
$ mkdir globbing
$ cd globbing
$ mkdir -p folder/{sub,another}folder/content/deepfolder/
touch macy stacy tracy "file with space" folder/{sub,another}folder/content/deepfolder/file
.hiddenfile
$ shopt -u nullglob
$ shopt -u failglob
$ shopt -u dotglob
$ shopt -u nocaseglob
$ shopt -u extglob
$ shopt -u globstar
Bash 内置的 extglob 选项可以扩展 glob 的匹配功能
shopt -s extglob
下列子模式包含有效的扩展 globs:
-
?(pattern-list)– 匹配给定模式的零次或一次出现 -
*(pattern-list)– 匹配给定模式的零次或多次出现 -
+(pattern-list)– 匹配给定模式的一次或多次出现 -
@(pattern-list)– 匹配给定模式之一 -
!(pattern-list)– 除给定模式之一外,匹配其他任何模式
模式列表是一个用 | 分隔的 globs 列表。
$ echo *([r-t])acy
stacy tracy
$ echo *([r-t]|m)acy
macy stacy tracy
$ echo ?([a-z])acy
macy
模式列表本身可以是另一个嵌套的扩展 glob。在上面的例子中,我们看到可以用 *(r-t)来匹配 tracy 和 stacy。这个扩展 glob 本身可以在否定的扩展 glob !(pattern-list) 中使用,以匹配 macy
$ echo !(*([r-t]))acy
macy
只要开头字母 r、s 和 t 的出现次数不为 0 或多于 0 次,就与之匹配,因此只有 macy 可能匹配。