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

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

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

Замечу, что следующее работает отлично:

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

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

Я нахожусь в Mac OS X.

Ответы

Ответ 1

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

справочная страница re_format

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

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

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

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

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

К сожалению, -E не переносится.

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

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

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

Резюме синтаксиса Regex Google Cache]

Ответ 2

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

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

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

find . -type f -regex ".*\.[mh]$"

Ответ 3

Что случилось с

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

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

Ответ 4

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

find . | grep ".*\(\h\|m\)"