Как использовать регулярное выражение с командой поиска?

298

У меня есть несколько изображений с именем сгенерированной строки uuid1. Например, 81397018-b84a-11e0-9d2a-001b77dc0bed.jpg. Я хочу узнать все эти изображения, используя команду "найти":

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

Но это не работает. Что-то не так с регулярным выражением? Может ли кто-нибудь помочь мне с этим?

thoslin
источник
7
может быть, изменить тип регулярного выражения По умолчанию это регулярные выражения Emacs , что бы это ни значило.
павильон

Ответы:

349
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 --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
@ Том, это способ регулярных выражений в поиске работ. Согласно man-странице, регулярное выражение соответствует всему пути к файлу, включая каталоги, что означает, что существует неявное "^ ... $"окружение вашего регулярного выражения. Он должен соответствовать ВСЕЙ строке результата.
Мэнни Д
2
Я не думаю , что вам нужен /в .*/потому , что .*соответствует нулю или более (почти) любого характера.
Джефф
2
Для тех (как я), которые не читали регулярное выражение должным образом в первый раз: обратите внимание на обратную косую черту, предшествующую специальным символам регулярного выражения, например:\{36\}
Лукас Уилсон-Рихтер
11
У меня были проблемы с поиском полного списка типов регулярных выражений (manpage не обновлен):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
Убедитесь в том , чтобы поставить -regextypeфлаг , прежде чем на -regexфлаг, в противном случае она не применяется!
Кристофер Орр
84

-regexВыражение находки соответствует полному имени , в том числе относительного пути от текущего каталога. Ибо find .это всегда начинается с ./любых каталогов.

Кроме того, это emacsрегулярные выражения, которые имеют другие экранирующие правила, чем обычные регулярные выражения egrep.

Если все они находятся непосредственно в текущем каталоге, то

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

должно сработать. (Я не совсем уверен - я не могу заставить подсчитанное повторение работать здесь.) Вы можете переключиться на выражения egrep -regextype posix-egrep:

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

(Обратите внимание, что все сказанное здесь для GNU find, я ничего не знаю о BSD, который также используется по умолчанию на Mac.)

Пауло Эберманн
источник
1
У меня были круглые скобки для нескольких совпадающих строк в моем регулярном выражении, поэтому posix-egrepтип работал для меня.
Palswim
2
Стоит отметить, -regextypeчто это вариант для GNU, findа не BSD (по крайней мере, не для Mac, похожего на BSD) find. Если эта опция недоступна, обязательно установите GNU find. Если на Mac это возможно с пакетом brew findutils. Найти можно через gfind.
DanCat
regextype posix-egrep сделал это за меня. Я думаю, что по умолчанию используется remaxtype emacs.
Infoclogged
35

Судя по другим ответам, похоже, что в этом может быть ошибка.

Однако вы можете сделать это следующим образом:

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

Возможно, вам придется немного настроить grep и использовать разные опции в зависимости от того, что вы хотите, но это работает.

yarian
источник
Работал хорошо для меня и обеспечивает большую степень свободы по отношению к регулярному выражению.
глаукон
3
Недостаток с этим является то , что вы не можете воспользоваться find«S -pruneфункциональности , которая пропустит через определенные каталоги в целом. Чаще всего это не очень важно, но стоит упомянуть.
Александр Берд
Я думаю, что все еще будет работать. Было бы опаснее использовать -exec - он будет работать на всех файлах, а не только на тех, которые позволяет пропустить grep.
tpb261
13

в Mac OS X (поиск BSD) : .*/совпадает с принятым ответом, префикс необходим для полного пути:

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

man findговорит, что -Eиспользует расширенную поддержку регулярных выражений

Стан Курдзиэль
источник
Кажется, -Eнедоступно в Ubuntu (протестировано в WSL Ubuntu)
Воинственный шимпанзе
2
@Clever Little Monkey - Нет, принятый ответ должен работать на Ubuntu, этот вариант предназначен специально для Mac OS X (или, возможно, другого варианта BSD, такого как FreeBSD)
Стэн Курдзил
8

Попробуйте использовать одинарные кавычки ('), чтобы избежать экранирования вашей строки. Помните, что выражение должно соответствовать всему пути, т.е. должно выглядеть так:

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

Кроме того, похоже, что моя находка (GNU 4.4.2) знает только основные регулярные выражения, особенно не синтаксис {36}. Я думаю, вам придется обойтись без этого.

thiton
источник
8

Простой способ - вы можете указать. * В начале, потому что поиск соответствует всему пути.

$ 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)
binbjz
источник
6

Вы должны использовать абсолютный путь к каталогу при применении инструкции find с регулярным выражением. В вашем примере

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"
прекрасный
источник