почему это регулярное выражение не работает: find ./ -regex '. * \ (m \ | h \) $ - PullRequest
22 голосов
/ 06 мая 2011

Почему это регулярное выражение не работает?

  find ./ -regex '.*\(m\|h\)$

Я заметил, что работает нормально:

  find ./ -regex '.*\(m\)$'

Но когда я добавляю "или h в конце имени файла", добавив \|h, это не работает. То есть он должен забрать все мои *.m и *.h файлы, но я ничего не получаю обратно.

Я в Mac OS X.

Ответы [ 4 ]

28 голосов
/ 06 мая 2011

В Mac OS X вы не можете использовать \| в базовом регулярном выражении, которое find использует по умолчанию.

re_format man page

[базовые] регулярные выражения отличаются в нескольких отношениях.|является обычным символом, и его функциональность не имеет эквивалента.

Самым простым решением в этом случае является изменение \(m\|h\) на [mh], например

find ./ -regex '.*[mh]$'

ИлиВы можете добавить опцию -E, чтобы указать находить вместо этого расширенные регулярные выражения.

find -E ./ -regex '.*(m|h)$'

К сожалению -E не переносимый.

Также обратите внимание, что если вы хотите толькосписок файлов, оканчивающийся на .m или .h, вы должны экранировать точку, например,

find ./ -regex '.*\.[mh]$'

Если вас это смущает (я тоже), есть отличная справочная таблица, которая показывает, какие функции поддерживаютсяв каких системах.

Синтаксическая сводка Regex [ Кэш Google ]

10 голосов
/ 06 мая 2011

Более эффективное решение - использовать флаг -o:

find . -type f \( -name "*.m" -o -name "*.h" \)

но если вы хотите использовать регулярное выражение:

find . -type f -regex ".*\.[mh]$"
3 голосов
/ 04 марта 2017

Ладно, это немного странно, но если вы не хотите нарушать ограничения поиска в OSX, вы можете просто передать результаты поиска в grep:

find . | grep ".*\(\h\|m\)"
1 голос
/ 06 мая 2011

Что не так с

find . -name '*.[mh]' -type f

Если вам нужны причудливые шаблоны, используйте find2perl и взломайте шаблон.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...