为什么连字符 - 在 find 命令的正则表达式中找不到?

Rya*_*yan 6 find regular-expression

要标识文件名中带有连字符-的文件,例如test-19.1.txtfind与正则表达式组合的命令似乎不匹配。

该命令find . -maxdepth 1 -regextype posix-egrep -regex '.*/[a-z0-9\-\.]+\.txt' -exec echo {} \;在 bash shell 中运行,并且未发现此类文件。如果从文件名中删除连字符,则正则表达式匹配。

使用regexr.com测试时相同的正则表达式成功。

phu*_*clv 15

要在字符类中包含连字符,它必须位于第一个或最后一个位置

来自find 手册 “find 和 locate 使用的正则表达式类型几乎与 GNU Emacs 中使用的相同”和来自Emacs 手册

  • [ ... ]
    • 要包含 a ‘-’‘-’请将其写为集合的第一个或最后一个字符,或将其放在一个范围之后。因此,‘[]-]’匹配‘]’‘-’

所以你的正则表达式应该是 '.*/[a-z0-9.-]+\.txt'

在 POSIX BRE & ERE 中,同样的规则适用

如果该<hyphen-minus>字符'^'在列表中首先出现(如果有的话)或最后出现,或作为范围表达式中的结束范围点,则该字符应被视为其自身。例如,表达式"[-ac]"and"[ac-]"是等价的并且匹配任何字符'a', 'c', 或'-'; "[^-ac]"and"[^ac-]"是等价的并且匹配除'a', 'c', or之外的任何字符'-';表达式"[%--]"匹配'%'和之间的任何字符'-';表达式"[--@]"匹配'-'和之间的任何字符'@';并且表达式"[a--@]"无效或等效于'@',因为字母'a'跟在符号之后'-'在 POSIX 语言环境中。要将 a<hyphen-minus>用作起始范围点,它应出现在括号表达式中或指定为整理符号;例如,"[][.-.]-0]",它匹配 a<right-square-bracket>或任何字符或整理在<hyphen-minus>0 和 0之间(包括 0)的整理元素。

如果括号表达式同时指定'-'']'']'则应放在括号表达式中的第一个(在 之后'^',如果有的话)和'-'最后一个。

常用表达

事实上,大多数正则表达式变体都具有相同的匹配连字符的规则

连字符可以包含在左括号之后,右括号之前,或否定插入符号之后。既[-x][x-]匹配的x或连字符。[^-x][^x-]匹配任何不是 x 或连字符的字符。这适用于本教程中讨论的所有风格。无法形成范围的字符类中其他位置的连字符可能会被解释为文字或错误。正则表达式的口味对此非常不一致。

字符类或字符集


ImH*_*ere 5

尝试;

find . -maxdepth 1 -regextype posix-egrep -regex '.*/[a-z0-9.-]+\.txt'
Run Code Online (Sandbox Code Playgroud)

在括号表达式内:

  • 破折号具有范围的特殊含义。只有当破折号位于开头(在 optional 之后^,如果使用)或结尾时,才会避免这种特殊含义。
  • 一般来说,反斜杠不会转义下一个字符,它是一个文字\. 特别是:不需要转义点,也没有办法-用反斜杠转义破折号 ( )的特殊含义。

所以,你写的内容[a-z0-9\-\.]被理解为范围从\\(或只是一个\)。