Использование нескольких условий в регулярном выражении find в оболочке

Вопрос или проблема

ИЗМЕНЕНО:
Мне нужно использовать -E для расширенного регулярного выражения.

У меня есть папка с этими файлами (просто пример):
структура директории

Я пытаюсь найти все файлы, которые:

  1. Начинаются и заканчиваются на #. (например, #hi.h#)
  2. Заканчиваются на ~. (например, file.txt~)

Я могу находить файлы по 1 условию или 2 условиям, но не могу объединить оба в одно регулярное выражение.

$ find . -regex "./.*~"
./lld~

$ find . -regex "./#.*#"
./#x2#
./#x#

Но эта команда не работает:

$ find . -regex "./(.*~$)|(#.*#)"

Что я делаю не так? Как я могу объединить эти регулярные выражения?

find . -regex "\./#.*#\|\./.*~"

Это работает для вас?

С помощью -regextype (GNU find)

Мне нужно использовать -E для расширенного регулярного выражения.

Вызовите find . -regextype help, чтобы узнать доступные опции. GNU find в моей системе Debian поддерживает немного. Другие реализации find могут либо поддерживать, либо не поддерживать -regextype. Это работает с GNU find:

find . -regextype posix-extended -regex '\./(.*~$|#.*#)'

Обратите внимание, что я немного отладил и упростил регулярное выражение (\./.*~$|\./#.*# тоже будет работать). Другие опции, которые работают для меня в этом конкретном случае: posix-egrep, egrep, posix-awk, awk, gnu-awk.


Без -regextype

Эта команда:

find . -regex '\./#.*#\|\./.*~'

где | экранирован, работает для меня. Спасибо другому ответу. Правильное экранирование ( и ) делает следующее также рабочим:

find . -regex '\./\(.*~$\|#.*#\)'

без использования расширенных регулярных выражений.


С помощью -o

Вам не обязательно объединять два выражения в одно. Если эти работают:

find . -regex '\./.*~'
find . -regex '\./#.*#'

то вы можете получить файлы, соответствующие одному регулярному выражению или другому, следующим образом:

find . -regex '\./.*~' -o -regex '\./#.*#'

Будьте осторожны: Почему find в Linux пропускает ожидаемые результаты, когда используется -o? Если вы хотите добавить больше тестов/действий до и/или после, то вам не нужно это:

find . -test1 -test2 -regex '\./.*~' -o -regex '\./#.*#' -test3 …

а это:

find . -test1 -test2 '(' -regex '\./.*~' -o -regex '\./#.*#' ')' -test3 …

Ответ или решение

Для поиска файлов с использованием регулярных выражений в командной строке Linux с помощью find, вы можете комбинировать несколько условий с помощью разных подходов. Давайте рассмотрим три основных метода: использование -regextype, простое экранирование, и использование логического оператора -o.

1. Использование опции -regextype

Если вы используете GNU find, вы можете указать тип регулярного выражения с помощью флага -regextype. Например, чтобы найти файлы, начинающиеся и заканчивающиеся на # или заканчивающиеся на ~, выполните следующую команду:

find . -regextype posix-extended -regex '\./(.*~$|#.*#)'

Эта команда работает благодаря тому, что мы используем расширенные регулярные выражения и комбинируем два условия в одну строку.

2. Простой экранированный вызов

Если вы хотите избежать использования -regextype, вы можете комбинировать условия с использованием экранирования. Например, следующая команда также вернет нужные файлы:

find . -regex '\./#.*#\|\./.*~'

Здесь | экранирован, что позволяет find правильно интерпретировать его как логическое "ИЛИ" между двумя регулярными выражениями.

Еще один вариант с использованием скобок:

find . -regex '\./\(.*~$\|#.*#\)'

Такой способ также позволяет работать с несколькими условиями, используя экранирование для скобок.

3. Использование оператора -o

Если вы не хотите объединять регулярные выражения в одно, вы можете просто использовать логический оператор -o (или):

find . -regex '\./.*~' -o -regex '\./#.*#'

Тем не менее, будьте осторожны с использованием -o. Если вы добавляете дополнительные проверки или действия, лучше использовать круглые скобки для группировки:

find . -test1 -test2 \( -regex '\./.*~' -o -regex '\./#.*#' \) -test3 …

Таким образом, использование дополнительных условий между регулярными выражениями не повлияет на выполнение команды.

Заключение

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

Оцените материал
Добавить комментарий

Капча загружается...