如何将正则表达式与 find 命令一起使用?

发布于 2024-11-26 11:49:50 字数 262 浏览 2 评论 0原文

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

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

但它不起作用。正则表达式有问题吗?

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:

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

But it doesn't work. Is something wrong with the regex?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

戴着白色围巾的女孩 2024-12-03 11:49:50
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'.
find . -regextype sed -regex ".*/[a-f0-9\-]\{36\}\.jpg"

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

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'.
冷情妓 2024-12-03 11:49:50

-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 上的默认版本。)

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

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

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:

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

黑凤梨 2024-12-03 11:49:50

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

但是,您可以这样做:

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

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

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

However you can do it this way instead:

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.

蝶…霜飞 2024-12-03 11:49:50

在 Mac OS X (BSD find) 上:与接受的答案效果相同。

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

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

注意:需要 .*/ 前缀来匹配完整路径:

出于比较目的,这里是GNU/Linux 版本:

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

on Mac OS X (BSD find): Same effect as the accepted answer.

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

man find says -E uses extended regex support

NOTE: the .*/ prefix is needed to match a complete path:

For comparison purposes, here's the GNU/Linux version:

$ find . -regextype sed -regex ".*/[a-f0-9\-]\{36\}\.jpg"
时常饿 2024-12-03 11:49:50

简单的方法 - 您可以在开头指定 .* 因为 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)

查找版本

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

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

find version

要走干脆点 2024-12-03 11:49:50

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

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

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

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:

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.

演出会有结束 2024-12-03 11:49:50

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

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"

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

find . -regextype posix-extended -regex "[a-f0-9\-]\{36\}\.jpg"
戏剧牡丹亭 2024-12-03 11:49:50

如果您想保持跨平台兼容性,我找不到能够以一致的方式跨不同版本的 find 运行的内置正则表达式搜索选项。

与 grep 结合

  1. 正如 @yarian 所建议的,您可以运行过度包含的查找,然后通过 grep:

find 运行输出。 | grep -E ''

这可能会很慢,但如果您需要使用完整的正则表达式并且无法将搜索重新格式化为,则将为您提供跨平台正则表达式搜索glob

重写为 glob

  1. -name 选项与 glob 兼容,后者将提供有限(但跨平台)的模式匹配。

您可以使用命令行上的所有模式,例如 * ? {} **。尽管不如完整的正则表达式那么强大,但您可以根据您的用例将搜索重新表述为全局。

互联网搜索globs - 许多详细介绍完整功能的教程都可以在线获取

If you want to maintain cross-platform compatibility, I could find no built-in regex search option that works across different versions of find in a consistent way.

Combine with grep

  1. As suggested by @yarian, you could run an over-inclusive find and then run the output through grep:

find . | grep -E '<POSIX regex>'

This is likely to be slow but will give you cross-platform regex search if you need to use a full regular expression and can't reformat your search as a glob

Rewrite as a glob

  1. The -name option is compatible with globs which will provide limited (but cross-platform) pattern matching.

You can use all the patterns that you would on the command line like * ? {} **. Although not as powerful as full regex, you might be able to reformulate your search to globs depending on your use-case.

Internet search for globs - many tutorials detailing full functionality are available online

晚风撩人 2024-12-03 11:49:50

我没有看到的一件事是如何将正则表达式与正则查找语法结合起来。

例如:我想在 BSD / Linux 上查找核心转储文件,我更改为我要扫描的根目录.. 例如: cd / 然后执行:

find \( -path "./dev" -o -path "./sys" -o -path "./proc" \) -prune -o -type f -regextype sed -regex ".*\.core$" -exec du -h {} \; 2> /dev/null

所以我使用 prune 命令来排除多个系统目录,然后对其余文件执行正则表达式。所有错误输出 (stderr) 都会被删除。

重要的部分是首先使用 Find 语法,然后使用正则表达式进行 OR (-o)。

One thing I don't see covered is how to combine regular expressions with regular find syntax.

Eg: I want to find core dump files on BSD / Linux, I change to the root I want to scan.. eg: cd / then execute:

find \( -path "./dev" -o -path "./sys" -o -path "./proc" \) -prune -o -type f -regextype sed -regex ".*\.core
quot; -exec du -h {} \; 2> /dev/null

So I am using the prune command to exclude multiple system directories, before doing regular expression on the remaining files. Any error output (stderr) is deleted.

The important part is to use the Find syntax first, then OR (-o) with the regular expression.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文