Как использовать команду find для поиска нескольких расширений

Ответы:

153

Используйте -oфлаг между различными параметрами.

find ./ -type f \( -iname \*.jpg -o -iname \*.png \) работает как шарм.

ПРИМЕЧАНИЕ Между скобкой и ее содержимым должен быть зазор, иначе он не будет работать.

Объяснение:

  • type -f - только поиск файлов (не каталогов)
  • \(- необходимо для type -fприменения ко всем аргументам
  • -o - логический оператор ИЛИ
  • -iname- нравится -name, но совпадение нечувствительно к регистру
Shadur
источник
Вам нужны скобки. Команда работает у меня без них. Они нужны для некоторых снарядов?
MikeD
2
@miked Команда будет «работать» без них, да, но вы получите попадания в каталоги, оканчивающиеся на .png, а также на файлы, оканчивающиеся на .jpg, что не совсем то, что было задумано.
Шадур
1
Спасибо за разъяснение! Символ type -fне распространяется и не применяется к обоим выражениям без скобок, поэтому find ./ -type f -iname \*.jpg -o -type f -iname \*.pngтакже работает ... хотя он на два символа длиннее :-)
MikeD
2
Это вопрос приоритета оператора. Так же, как a * b + cотличается отa * (b + c)
Шадур
2
@jdhao Хороший улов, исправлено.
Shadur
86

Вы можете комбинировать критерии с , -oкак было предложено Shadur . Обратите внимание, что он -oимеет более низкий приоритет, чем сопоставление, поэтому вам могут понадобиться скобки.

find . -name '*.jpg' -o -name '*.png'
find . -mtime -7 \( '*.jpg' -o -name '*.png' \)  # all .jpg or .png images modified in the past week

В Linux, вы можете использовать , -regexчтобы объединить расширения в terser образом. Синтаксис регулярного выражения по умолчанию - Emacs ( базовые регулярные выражения плюс несколько расширений, например, \|для чередования); есть возможность переключиться на расширенные регулярные выражения .

find -regex '.*\.\(jpg\|png\)'
find -regextype posix-extended -regex '.*\.(jpg|png)'

В FreeBSD, NetBSD и OSX вы можете использовать в -regexсочетании с -Eрасширенными регулярными выражениями.

find -E . -regex '.*\.(jpg|png)'
жилль
источник
Всегда лучше использовать -inameвместо -name- тогда вы также захватите image.JPGиimage.PnG
ccpizza
40

Это более правильно:

find . -iregex '.*\.\(jpg\|gif\|png\|jpeg\)$'
Димитрий
источник
10
Почему вы говорите, что это «более» правильно?
Кевин
2
@Kevin Я думаю, потому что -iregexсовпадает jpgтак же, как JPG Jpg jpGи тому подобное. Я думаю, что $это не нужно.
ot--
Это прекрасно работает на MinGW .
Питер Мортенсен
2
Во-первых, вы пропустили папку поиска в качестве первого аргумента, который выдаст ошибку. Во-вторых, при экранировании OSX скобки не будут работать, и вместо этого это следует использовать: find -E . -iregex '.*\.(jpg|png|gif)'как показано в ответе @ sorin.
ccpizza
8

Чтобы было понятно, единственная опция, которая работает в Linux, Unix и MacOS:

find -E . -regex '.*\.(jpg|png)'

Это потому, что версия OS X немного отличается, но важно писать вещи, которые хорошо работают на большинстве платформ.

Сорин
источник
2
-E флаг недействителен для поиска в Ubuntu 14.04
gogaman
Флаг -E также недопустим в MinGW (по крайней мере, версия / конфигурация, на которой я его пробовал (конфигурация по умолчанию для конкретной версии)).
Питер Мортенсен,
Какая часть -type f \( -iname \*.png -o -iname \*.jpg\)не работает на OSX?
Шадур
-3
/\.(jpe?g|png|gif|bmp)$/i;

Используй это.

Рохит Гур
источник
5
Возможно, вам придется объяснить это немного.
хаос