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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6844785/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-05 05:18:00  来源:igfitidea点击:

How to use regex with find command?

regexlinuxfind

提问by thoslin

I have some images named with generated uuid1 string. For example 81397018-b84a-11e0-9d2a-001b77dc0bed.jpg. I want to find out all these images using "find" command:

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

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

But it doesn't work. Something wrong with the regex? Could someone help me with this?

但它不起作用。正则表达式有问题吗?有人可以帮我解决这个问题吗?

采纳答案by Susam Pal

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

Note that you need to specify .*/in the beginning because findmatches the whole path.

请注意,您需要.*/在开头指定,因为find匹配整个路径。

Example:

例子:

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

My version of 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'.

回答by thiton

Try to use single quotes (') to avoid shell escaping of your string. Remember that the expression needs to match the whole path, i.e. needs to look like:

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

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

Apart from that, it seems that my find (GNU 4.4.2) only knows basic regular expressions, especially not the {36} syntax. I think you'll have to make do without it.

除此之外,我的发现(GNU 4.4.2)似乎只知道基本的正则表达式,尤其是不知道 {36} 语法。我认为没有它你将不得不凑合。

回答by Pa?lo Ebermann

The -regexfind expression matches the whole name, including the relative path from the current directory. For find .this always starts with ./, then any directories.

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

Also, these are emacsregular expressions, which have other escaping rules than the usual egrep regular expressions.

此外,这些是emacs正则表达式,与通常的 egrep 正则表达式相比,它们具有其他转义规则。

If these are all directly in the current directory, then

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

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

should work. (I'm not really sure - I can't get the counted repetition to work here.) You can switch to egrep expressions by -regextype posix-egrep:

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

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

(Note that everything said here is for GNU find, I don't know anything about the BSD one which is also the default on Mac.)

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

回答by yarian

Judging from other answers, it seems this might be find's fault.

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

However you can do it this way instead:

但是,您可以这样做:

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

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

You might have to tweak the grep a bit and use different options depending on what you want but it works.

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

回答by Lovely

You should use absolute directory path when applying find instruction with regular expression. In your example, the

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

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

should be changed into

应该改成

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

In most Linux systems, some disciplines in regular expression cannot be recognized by that system, so you have to explicitly point out -regexty like

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

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

回答by binbjz

Simple way - you can specify .* in the beginning because find matches the whole path.

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

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

find version

查找版本

$ 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)

回答by Stan Kurdziel

on Mac OS X (BSD find): Same as accepted answer, the .*/prefix is needed to match a complete path:

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

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

man findsays -Euses extended regex support

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