Як користуватися регулярним виразом з командою find?


297

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

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

Але це не працює. Щось не в порядку з виразкою? Може хтось допоможе мені в цьому?


7
можливо, змінити регестип. За замовчуванням - регулярні вирази Emacs , що б це не означало.
pavium

Відповіді:


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 --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
@Тому це шлях, який регулярно виражає у пошуку творів. Згідно з довідковою сторінкою, регулярний вираз відповідає всій траєкторії файлу, включаючи каталоги, а це означає, що "^ ... $"навколо викладу є неявна інформація . Він повинен відповідати цілому РЕЗУЛЬТАТУ.
Manny D

2
Я не думаю , що вам потрібен /в .*/тому , що .*відповідає нулю або більше (майже) будь-якого характеру.
Джефф

2
Для тих (як я), які не прочитали регулярно регулярний вираз: Зверніть увагу на зворотні риси, що передують спеціальним символам регулярного виразів, наприклад:\{36\}
Лукас Вілсон-Ріхтер,

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'.
Ной Суссман,

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, я не знаю нічого про BSD, який також є за замовчуванням на Mac.)


1
У моєму регулярному виразі були круглі дужки для декількох збігаються рядків, тому posix-egrepтип працював для мене.
palswim

2
Щось зауважимо, -regextypeце варіант для GNU, findа не BSD (принаймні, не для Mac BSD) find. Якщо ця опція недоступна, не забудьте встановити GNU find. Якщо на Mac це можливо з пакетом заварки findutils. Тоді пошук доступний через gfind.
DanCat

regextype posix-egrep зробив для мене завдання. Я думаю, що за замовчуванням є regextype emacs.
infoclogged

35

Судячи з інших відповідей, здається, це може бути виною.

Однак ви можете зробити це так:

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

Можливо, вам доведеться трохи налаштувати греп і використовувати різні варіанти залежно від того, що ви хочете, але це працює.


Добре працював для мене і забезпечує великий ступінь свободи по відношенню до регексу.
glaucon

3
Недоліком цього є те, що ви не можете скористатися функціоналом find's, -pruneякий взагалі буде пропускати певні каталоги. Найчастіше це не дуже важливо, але варто згадати.
Олександр Птах

-Присінь все одно буде працювати, я думаю. Було б небезпечніше використовувати -exec - він би запускався на всіх файлах, а не тільки на тих, які дозволяє передавати grep.
tpb261

13

на Mac OS X (BSD find) : те саме, що прийнято відповідь, .*/префікс потрібен для відповідності цілому шляху:

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

man findговорить, що -Eвикористовує розширену підтримку регулярних виразів


Здається , -Eнемає в наявності на Ubuntu (перевірено на Ubuntu WSL)
войовнича Шимпанзе

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 . -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 з регулярним виразом. У вашому прикладі

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"
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.