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

tho*_*lin 268 regex linux find

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

find . -regex "[a-f0-9\-]\{36\}\.jpg".
Run Code Online (Sandbox Code Playgroud)

但它不起作用.正则表达式出了什么问题?有人可以帮我吗?

Sus*_*Pal 318

find . -regextype sed -regex ".*/[a-f0-9\-]\{36\}\.jpg"
Run Code Online (Sandbox Code Playgroud)

请注意,您需要.*/在开头指定,因为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
Run Code Online (Sandbox Code Playgroud)

我的发现版本:

$ 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'.
Run Code Online (Sandbox Code Playgroud)

  • 我无法找到正则表达式类型的完整列表(联机帮助页不是最新的):`有效类型是'findutils-default','awk','egrep','ed','emacs','gnu-awk' ,'grep','posix-awk','posix-basic','posix-egrep','posix -extended','posix-minimal-basic','sed'. (8认同)
  • @Tom是正确的查找工作方式.根据手册页,正则表达式匹配整个文件路径,包括目录,这意味着你的正则表达式周围有一个隐含的"^ ... $".它必须与WHOLE结果行匹配. (2认同)
  • 我认为你不需要 `.*/` 中的 `/`,因为 `.*` 匹配零个或多个(几乎)任何字符。 (2认同)
  • 对于那些第一次没有正确读取正则表达式的人(比如我):注意特殊正则表达式字符之前的反斜杠,例如:`\ {36 \}` (2认同)
  • 确保在-regex标志之前*放置-regextype标志,否则不适用! (2认同)
  • @osullic我通过运行“find -regextype help”获得了有效正则表达式类型的列表 (2认同)

Paŭ*_*ann 74

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

此外,这些是emacs正则表达式,其具有除通常的egrep正则表达式之外的其他转义规则.

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

find . -regex '\./[a-f0-9\-]\{36\}\.jpg'
Run Code Online (Sandbox Code Playgroud)

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

find . -regextype posix-egrep -regex '\./[a-f0-9\-]{36}\.jpg'
Run Code Online (Sandbox Code Playgroud)

(请注意,这里所说的一切都是针对GNU查找的,我对BSD一无所知,这也是Mac上的默认设置.)

  • 我的正则表达式中有多个匹配字符串的括号,所以 `posix-egrep` 类型对我有用。 (3认同)
  • 值得注意的是,`-regextype`是GNU`find`的一个选项,而不是BSD(至少不是Mac BSD)`find`.如果此选项不可用,请确保安装GNU find.如果在Mac上可以使用brew包`findutils`.然后通过`gfind`查找. (2认同)
  • `posix-egrep` 可以缩写为 `egrep` (2认同)

yar*_*ian 31

从其他答案来看,似乎这可能是错误的.

但是你可以这样做:

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

您可能需要稍微调整一下grep并根据您的需要使用不同的选项,但它可以正常工作.

  • 这样做的一个缺点是你无法利用`find`的`-prune`功能,它将完全跳过某些目录.大多数情况下这并不重要,但值得一提. (2认同)
  • `找到。*` 相当于“find”(较短的命令)。 (2认同)

thi*_*ton 7

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

 find . -regex '\./[a-f0-9-]*.jpg'
Run Code Online (Sandbox Code Playgroud)

除此之外,我的发现(GNU 4.4.2)似乎只知道基本的正则表达式,特别是{36}语法.我想你必须没有它.


bin*_*bjz 7

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

$ find . -regextype egrep -regex '.*[a-f0-9\-]{36}\.jpg$'
Run Code Online (Sandbox Code Playgroud)

查找版本

$ 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)
Run Code Online (Sandbox Code Playgroud)


小智 6

在使用正则表达式应用查找指令时,应使用绝对目录路径.在你的例子中,

find . -regex "[a-f0-9\-]\{36\}\.jpg"
Run Code Online (Sandbox Code Playgroud)

应改成

find . -regex "./[a-f0-9\-]\{36\}\.jpg"
Run Code Online (Sandbox Code Playgroud)

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

find . -regextype posix-extended -regex "[a-f0-9\-]\{36\}\.jpg"
Run Code Online (Sandbox Code Playgroud)


Sta*_*iel 5

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

$ find -E . -regex ".*/[a-f0-9\-]{36}.jpg"
Run Code Online (Sandbox Code Playgroud)

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

  • 似乎 `-E` 在 Ubuntu 上不可用(在 WSL Ubuntu 上测试) (4认同)
  • @Clever Little Monkey - 不,接受的答案应该适用于 Ubuntu,这个变体是专门针对 Mac OS X 的(或者可能是另一个像 FreeBSD 这样的 BSD 变体) (2认同)