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