查找在同一 CWD 中使用 regexp,但不能从另一个目录中使用

查找在同一 CWD 中使用 regexp,但不能从另一个目录中使用

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

有效的是这个

  • 实施例1
find $directory -maxdepth 1 -type d -name "test*"

这给了我一些结果。

这也有效

  • 实施例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}\$"

但是,使用 a$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}\$"

为什么会这样?

谢谢

答案1

-regex(非标准),就像-path文件完整路径上的标准匹配一样。这些路径以 的内容开头,$directory后跟 找到的目录和文件find。因此,如果$directory/some/dir-regex将与正则表达式匹配/some/dir/file-discovered-by-find,并且永远不会在这里匹配,因为第一个字符是 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}'

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

也就是说,让您的模式(这里保证不包含/)在任何匹配的内容之后/(并且一直到文件路径的末尾($也暗示如此)匹配,而不是在匹配的内容之后$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/)

与 GNUfind相比,它有几个优点:

  • 即使在非 GNU 系统上也可以工作(消除对 GNU 的依赖find
  • 即使$directory开始也有效-
  • 给你一个排序列表
  • in 中zsh[a-zA-Z0-9]匹配的内容不是随机的,也不随区域设置的变化而变化,例如 in find,并且匹配我认为您想要匹配的字符,并且仅匹配它们。在 中find,您需要[abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789]获得同等的东西。
  • 即使$directory是目录的符号链接它也可以工作(尽管您可以为此添加-H选项)。find
  • 即使文件路径(在本例中为 的内容$directory)包含在当前语言环境中不形成有效字符的字节序列(find' -regexs.*无法匹配这些字节,因为.仅匹配有效字符),它也可以工作。
  • 您可以直接使用它(作为命令的参数、循环遍历等等),而不是打印该列表。
  • 您还可以使用诸如(<0-255>~????*)匹配 0 到 255 之间由不超过 3 位数字组成的十进制数字或(<0-255>~0?*)不带前导 0 的数字之类的内容,zshglob 是极少数支持匹配数字范围的模式匹配 API 之一。

相关内容