我当前路径有 3 个目录。
$ls
a_0db_data a_clean_0db_data a_clean_data
$ls a_*_data
a_0db_data:
a_clean_0db_data:
a_clean_data:
$ls a_[a-z]*_data
a_clean_0db_data:
a_clean_data:
我预计最后一个 ls 命令仅匹配a_clean_data
.为什么它也匹配包含的那个0
?
bash --version
GNU bash, version 4.2.24(1)-release (i686-pc-linux-gnu)
答案1
答案2
所以问题是:为什么a_[a-z]*_data
匹配a_clean_0db_data
?
这可以分解为四部分:
a_
匹配 的开头a_clean_0db_data
,留下clean_0db_data
待匹配[a-z]
匹配范围内的任何字符a-z
(例如c
),留下lean_0db_data
待匹配*
匹配任意数量的字符,例如lean_0db
_data
匹配尾随的_data
在正则表达式中,[a-z]*
意味着a..z 范围内的任意数量的字符(包括零个),但您正在处理 shell 通配符,而不是正则表达式。
如果您需要正则表达式,一些find
实现有一个-regex
谓词:
find . -maxdepth 1 -regex "^.*/a_[a-z]*_data$"
此处-maxdepth
仅将搜索结果限制为您所在的文件夹。正则表达式匹配全部的文件名,因此我添加了一个^.*/
来匹配路径部分
答案3
*
在 shell 模式中匹配 0 个或多个字符。不要与*
正则表达式运算符混淆,这意味着0 个或多个前面的原子。
*
基本 shell 模式中没有与 regexp 等效的东西。然而,各种 shell 对此都有扩展。
ksh
有*(something)
:ls a_*([a-z])_data
bash
你可以在withshopt -s extglob
或zsh
with中拥有相同的内容setopt kshglob
:shopt -s extglob ls a_*([a-z])_data
在启用
zsh
时extendedglob
,#
相当于 regexp*
:setopt extendedglob ls a_[a-z]#_data
在最新版本的 中
ksh93
,您还可以在 glob 中使用正则表达式。这里与扩展常用表达:ls ~(E:a_[a-z]*_data)
请注意,[a-z]
根据当前区域设置匹配不同的内容。它通常只匹配区域设置中的 26a
到z
拉丁非重音字母C
。在其他语言环境中,它通常匹配更多,但并不总是有意义。要匹配您所在区域中的字母,您可能更喜欢[[:alpha:]]
.