为什么[az]星号匹配数字?


13

我在当前路径下有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)

2
这个问题更多的正则表达式和水珠之间的区别。
terdon

4
因此,a_*_data匹配任何一个文件的事实都不会令您感到惊讶吗?
Cthulhu 2014年

@克苏鲁你抓到我了!
user13107 2014年

Answers:


29

[a-z]部分与数字不匹配;是*。您可能会混淆shell 遍历正则表达式

诸如此类的工具可以grep接受各种形式的正则表达式(默认情况下为基本-E对于扩展-P则为Perl正则表达式

例如(-v反转比赛)

$ ls a_[a-z]*_data | grep -v "[0-9]"
a_clean_data

如果要使用bash正则表达式,下面是有关如何测试变量$ref是否为整数的示例:

re='^[0-9]+$'
if ! [[ $ref =~ $re ]] ; then
  echo "error"
fi

那么如何使用bash正则表达式呢?(见tldp.org/LDP/Bash-Beginners-Guide/html/sect_04_01.html
user13107


21

所以问题是:为什么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 globbing,而不是正则表达式。

如果要使用正则表达式,则有一些find实现可以-regex断言:

find . -maxdepth 1 -regex "^.*/a_[a-z]*_data$"

-maxdepth这里只是限制搜索结果你在该文件夹的正则表达式的匹配整个文件名,所以我添加了一个^.*/到路径部分匹配


11

*在shell模式中,匹配0个或多个字符。请勿将它与*正则表达式运算符混淆,后者表示0个或多个前面的atom

*基本shell模式中没有等效的regexp 。但是,各种外壳对此都有扩展。

  • ksh*(something)

    ls a_*([a-z])_data
  • 你可以有相同的bash使用shopt -s extglobzsh使用setopt kshglob

    shopt -s extglob
    ls a_*([a-z])_data
  • zshextendedglob启用,#是相当于正则表达式*

    setopt extendedglob
    ls a_[a-z]#_data
  • 在的最新版本中ksh93,您还可以在glob中使用正则表达式。这里带有扩展的正则表达式:

    ls ~(E:a_[a-z]*_data)

请注意,[a-z]根据当前语言环境匹配不同的内容。它一般只匹配了26 az在拉美的非重音字母C的语言环境。在其他语言环境中,它通常匹配更多,并且并不总是有意义。要在您的语言环境中匹配字母,您可能更喜欢[[:alpha:]]


您能否举一个[a-z]比C语言环境中匹配的26个字母更多的匹配示例?我从上次查看时记得的是,实际上在Unix变体中使用的所有编码都以ISO-646为基础(然后,上面的128个代码以不同的方式直接用于ISO-8859-X等编码中的字符,编码(例如UTF-8或EUC系列)。甚至AIX也没有EBCDIC语言环境(至少对我来说可用)。我记得曾经尝试查找POSIX / UNIX标准是否要求它,但是我不记得结果了。
AProgrammer 2014年

1
@AProgrammer,它与编码无关,它基于排序顺序(LC_COLLATE)。[a-z]通常,无论该编码中的代码点是否在a和z的代码点之间,在字符集拥有它们的语言环境中通常包括éí(但不是必须ź)。仅C语言环境保证基于代码点值的排序顺序。有关更多详细信息,请参见此其他答案
斯特凡Chazelas

好的,我错过的是该范围是根据当前的整理顺序进行解释的。
AProgrammer
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.