如何在find命令中使用正则表达式?


297

我有一些用生成的uuid1字符串命名的图像。例如81397018-b84a-11e0-9d2a-001b77dc0bed.jpg。我想使用“查找”命令找出所有这些图像:

find . -regex "[a-f0-9\-]\{36\}\.jpg".

但这是行不通的。正则表达式有问题吗?有人可以帮我吗?


7
也许改变正则表达式。缺省是Emacs正则表达式,无论什么意思。
pavium 2011年

Answers:


348
find . -regextype sed -regex ".*/[a-f0-9\-]\{36\}\.jpg"

请注意,.*/由于find与整个路径匹配,因此需要在开头指定。

例:

susam@nifty:~/so$ find . -name "*.jpg"
./foo-111.jpg
./test/81397018-b84a-11e0-9d2a-001b77dc0bed.jpg
./81397018-b84a-11e0-9d2a-001b77dc0bed.jpg
susam@nifty:~/so$ 
susam@nifty:~/so$ find . -regextype sed -regex ".*/[a-f0-9\-]\{36\}\.jpg"
./test/81397018-b84a-11e0-9d2a-001b77dc0bed.jpg
./81397018-b84a-11e0-9d2a-001b77dc0bed.jpg

我的find版本:

$ find --version
find (GNU findutils) 4.4.2
Copyright (C) 2007 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Written by Eric B. Decker, James Youngman, and Kevin Dalley.
Built using GNU gnulib version e5573b1bad88bfabcda181b9e0125fb0c52b7d3b
Features enabled: D_TYPE O_NOFOLLOW(enabled) LEAF_OPTIMISATION FTS() CBO(level=0) 
susam@nifty:~/so$ 
susam@nifty:~/so$ find . -regextype foo -regex ".*/[a-f0-9\-]\{36\}\.jpg"
find: Unknown regular expression type `foo'; valid types are `findutils-default', `awk', `egrep', `ed', `emacs', `gnu-awk', `grep', `posix-awk', `posix-basic', `posix-egrep', `posix-extended', `posix-minimal-basic', `sed'.

4
@Tom是正则表达式在查找中的工作方式。根据手册页,正则表达式匹配整个文件路径(包括目录),这意味着"^ ... $"您的正则表达式周围存在隐式内容。它必须匹配整个结果行。
Manny D

2
我认为您不需要/in,.*/因为可以.*匹配零个或多个(几乎)任何字符。
杰夫

2
对于那些第一次没有正确阅读正则表达式的人(如我):请注意正则表达式特殊字符前的反斜杠,例如:\{36\}
Lucas Wilson-Richter

11
我很难找到正则表达式类型的完整列表(联机帮助页不是最新的):valid types are 'findutils-default', 'awk', ' egrep', 'ed', 'emacs', 'gnu-awk', 'grep', 'posix-awk', 'posix-basic', 'posix-egrep', 'posix -extended', 'posix-minimal-basic', 'sed'.
Noah Sussman

4
确保把-regextype标志之前-regex标志,否则不适用!
Christopher Orr

84

-regex发现表达式匹配的全名,包括从当前目录的相对路径。为此,find .始终以开头./,然后是任何目录。

还有,这些是 emacs正则表达式,除了常规的egrep正则表达式外,还具有其他转义规则。

如果这些都直接在当前目录中,则

find . -regex '\./[a-f0-9\-]\{36\}\.jpg'

应该管用。(我不太确定-我无法获得计算的重复次数在这里工作。)您可以通过-regextype posix-egrep以下方式切换到egrep表达式:

find . -regextype posix-egrep -regex '\./[a-f0-9\-]{36}\.jpg'

(请注意,这里所说的所有内容都是供GNU查找的,我对BSD一无所知,这也是Mac上的默认设置。)


1
我的正则表达式中有多个匹配字符串的括号,因此该posix-egrep类型适用于我。
palswim 2014年

2
需要注意的是,它-regextype是GNU find而不是BSD 的选项(至少不是Mac BSD样的)find。如果此选项不可用,请确保安装GNU find。如果在Mac上,则可以使用brew包装findutils。然后可以通过查找gfind
DanCat

regextype posix-egrep为我完成了任务。我认为默认值为regextype emacs。
infoclogged

35

从其他答案来看,这似乎是find的错。

但是,您可以用这种方式代替:

find . * | grep -P "[a-f0-9\-]{36}\.jpg"

您可能需要稍微调整grep并根据需要使用不同的选项,但是它可以工作。


对我来说效果很好,并且在正则表达式方面提供了很大的自由度。
glaucon 2014年

3
这样做的缺点是您无法利用find-prune功能,该功能将完全跳过某些目录。通常,这并不是很重要,但是值得一提。
亚历山大·伯德

-prune仍然可以使用,我猜。使用-exec会更危险-它会在所有文件上运行,而不仅是grep允许传递的文件。
tpb261

13

在Mac OS X上(找到BSD):与接受的答案相同,.*/需要前缀以匹配完整路径:

$ find -E . -regex ".*/[a-f0-9\-]{36}.jpg"

man find-E使用扩展的正则表达式支持


似乎-E在Ubuntu上不可用(在WSL Ubuntu上测试)
Warlike黑猩猩

2
@Clever Little Monkey-不,接受的答案应该在Ubuntu上有效,此变体专门针对Mac OS X(或也许是另一个BSD变体,如FreeBSD)
Stan Kurdziel

8

尝试使用单引号(')避免对字符串进行外壳转义。请记住,表达式需要匹配整个路径,即需要看起来像:

 find . -regex '\./[a-f0-9-]*.jpg'

除此之外,似乎我的发现(GNU 4.4.2)仅了解基本的正则表达式,尤其是{36}语法。我认为您将不得不放弃它。


8

简单方法-您可以在开头指定。*,因为find匹配整个路径。

$ find . -regextype egrep -regex '.*[a-f0-9\-]{36}\.jpg$'

查找版本

$ find --version
find (GNU findutils) 4.6.0
Copyright (C) 2015 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later 
<http://gnu.org/licenses/gpl.html>.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Written by Eric B. Decker, James Youngman, and Kevin Dalley.
Features enabled: D_TYPE O_NOFOLLOW(enabled) LEAF_OPTIMISATION 
FTS(FTS_CWDFD) CBO(level=2)

6

在使用带有正则表达式的查找指令时,应使用绝对目录路径。在您的示例中,

find . -regex "[a-f0-9\-]\{36\}\.jpg"

应该变成

find . -regex "./[a-f0-9\-]\{36\}\.jpg"

在大多数Linux系统中,该系统无法识别正则表达式中的某些规则,因此您必须明确指出-regexty

find . -regextype posix-extended -regex "[a-f0-9\-]\{36\}\.jpg"
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.