在同一个 CWD 中查找使用正则表达式而不是从另一个目录中查找

von*_*otz 0 bash find regular-expression

我有一个 find 命令,我想从一个任意目录发出它,用一个$directory变量代替.当前工作目录的点。

这是什么工作

  • 示例 1
find $directory -maxdepth 1 -type d -name "test*"
Run Code Online (Sandbox Code Playgroud)

这给了我一些结果。

这也有效

  • 示例 2
find . -maxdepth 1 -type d -regextype posix-extended -regex "^./[a-zA-Z0-9]+([-_]?[a-zA-Z0-9]+)*-[0-9]{1,3}(.[0-9]{1,3}){,3}\$"
Run Code Online (Sandbox Code Playgroud)

但是,$directory它不起作用。请注意,我删除./了正则表达式开头的 。

  • 示例 3
find $directory -maxdepth 1 -type d -regextype posix-extended -regex "^[a-zA-Z0-9]+([-_]?[a-zA-Z0-9]+)*-[0-9]{1,3}(.[0-9]{1,3}){,3}\$"
Run Code Online (Sandbox Code Playgroud)

为什么呢?

谢谢

Sté*_*las 5

-regex(非标准),就像标准-path匹配文件的完整路径一样。这些路径以 的内容开头,$directory后跟find. 所以 if $directoryis /some/dir-regex将匹配正则表达式/some/dir/file-discovered-by-find,并且永远不会在这里匹配,因为第一个字符是 a /,而不是 a alnum。

在第一种情况下,你的正则表达式开始^./(应该是^\./作为.一个正则表达式运算符,或者只是\./因为^在GNU隐含find-regex)的$directory存在.

您需要对 做类似的事情$directory,记住$directory( ^$*()+[]?.\...)中的所有正则表达式运算符都需要转义。但在这里你也可以这样做:

find "$directory" -maxdepth 1 -type d -regextype posix-extended \
  -regex '.*/[[:alnum:]]+([-_][[:alnum:]]+)*-[[:digit:]]{1,3}(\.[[:digit:]]{1,3}){0,3}'
Run Code Online (Sandbox Code Playgroud)

(我也替换.\.因为我怀疑您想匹配文字.而不是任何字符,并删除了?此处不需要的 )。

也就是说,让你的模式(这里保证不包含 a /)在 any 之后匹配/(并且直到文件路径的结尾$也暗示)而不是在匹配的东西之后$directory

使用zsh -o extendglob,您可以执行以下操作:

set -o extendedglob
w=[0-9a-zA-Z] d=[0-9]
print -rC1 -- $directory/$~w##([-_]$~w##)#-$~d(#c1,3)(.$~d(#c1,3))(#c0,3)(#q/)
Run Code Online (Sandbox Code Playgroud)

与 GNU 相比,它有几个优点find

  • 即使在非 GNU 系统上也能工作(删除对 GNU 的依赖find
  • 即使$directory-
  • 给你一个排序的列表
  • in zsh[a-zA-Z0-9]匹配的内容不是随机的,不会随语言环境而变化,例如 infind并且匹配我想您想要匹配的字符,并且只匹配它们。在 中find,您需要[abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789]获得等价物。
  • 即使$directory是指向目录的符号链接,它也能工作(不过,您可以为此添加-H选项find)。
  • 它的工作原理,即使该文件的路径(在这种情况下的内容$directory)包含不构成在当前区域有效字符的字节序列(find-regex.*不能在那些符合作为.唯一有效的字符匹配)。
  • 您可以直接使用它而不是打印该列表(作为命令的参数,循环它等)
  • 您还可以使用诸如(<0-255>~????*)匹配从 0 到 255 由不超过 3 位数字组成的十进制数字或(<0-255>~0?*)那些没有前导 0 的数字之类的东西,zshglobs 是支持匹配数字范围的极少数模式匹配 API 之一。