- Find with regex
- 2 Answers 2
- How to use regex in file find
- 5 Answers 5
- Proof of Concept
- Not the answer you’re looking for? Browse other questions tagged bash unix or ask your own question.
- Linked
- Related
- Hot Network Questions
- Subscribe to RSS
- Понимание -regex с GNU find
- Задний план
- Поиск файлов с ls
- Поиск файлов с помощью find
- Вопросов
- Блог о системном администрировании. Статьи о Linux, Windows, СХД NetApp и виртуализации.
- 1. Традиционные регулярные выражения (они же основные, базовые и basic regular expressions (BRE))
- 2. Расширенные регулярные выражения (они же extended regular expressions (ERE))
- 3. Регулярные выражения, совместимые с Perl (они же Perl-compatible regular expressions (PCRE))
- Перечисление |
- Группировка или объединение ( )
- Квантификация <> ? * +
- Жадность regex
Find with regex
i’m beginning in bash script but here is my problem
i’ve been struggling with the find.
When i do find . ! -regex «.*(jpeg|jpg|gif|pdf)+$» the find can’t find anything though there is actually files not with this extension. As if it doesn’t recognize the regex group
I’ve found find . ! \( -name ‘*.jpeg’ -o -name ‘*.jpg’ -o -name ‘*.gif’ \)
My question is : Is there not a better way to do this ?
2 Answers 2
The proper regEx should have been
Notice the inclusion of . after the .* to match the character before file-name extension and escape character for each of the types associated.
Remember you are negating the regEx to exclude the files of the extensions mentioned. To actually list the files needed only of these extensions, drop the ! as
As if it doesn’t recognize the regex group
That’s exactly what’s happening.
There’s nothing wrong with your regex at all, but it’s written in a PCRE or ERE dialect that find doesn’t expect. If you tell find to interpret it as ERE, it will match as you intended:
It would also work just fine by default in Perl, Java, RE2, egrep , bash =
, awk , and a whole lot of other tools that also use PCRE or ERE.
However, it does not work in Emacs or BRE, which is what GNU and macOS find expect respectively.
Inian’s solution works by rewriting your pattern from ERE style to Emacs style, where \(\|\) is used instead of (|) (as well as making other improvements to it).
tl;dr: Copy-pasting a regex from one tool to another is like copy-pasting a function from Java to C#. They look very similar and it may even work, but it’s likely to require at least some tweaking.
Источник
How to use regex in file find
I was trying to find all files dated and all files 3 days or more ago.
It is not listing anything. What is wrong with it?
5 Answers 5
- -name uses globular expressions, aka wildcards. What you want is -regex
- To use intervals as you intend, you need to tell find to use Extended Regular Expressions via the -regextype posix-extended flag
- You need to escape out the periods because in regex a period has the special meaning of any single character. What you want is a literal period denoted by \.
- To match only those files that are greater than 3 days old, you need to prefix your number with a + as in -mtime +3 .
Proof of Concept
Use -regex not -name, and be aware that the regex matches against what find would print, e.g. «/home/test/test.log» not «test.log»
You may not need a regex, try:
You will want the +1 in order to match 1, 2, 3 .
From the man page:
Also, I don’t believe find supports regex extensions such as \d . You need to use 2 .
Just little elaboration of regex for search a directory and file
Find a directroy with name like book
Find a file with name like book word
Not the answer you’re looking for? Browse other questions tagged bash unix or ask your own question.
Linked
Related
Hot Network Questions
Subscribe to RSS
To subscribe to this RSS feed, copy and paste this URL into your RSS reader.
site design / logo © 2021 Stack Exchange Inc; user contributions licensed under cc by-sa. rev 2021.10.8.40416
By clicking “Accept all cookies”, you agree Stack Exchange can store cookies on your device and disclose information in accordance with our Cookie Policy.
Источник
Понимание -regex с GNU find
Задний план
У меня есть то, что, по моему мнению, должно быть простым. Я хочу найти все файлы с «cisco» в имени и сделать что-то с этими файлами (через xargs ).
Поиск файлов с ls
Прежде чем использовать xargs , первым шагом будет перечисление всех соответствующих файлов. Список файлов легко с ls | grep cisco ls | grep cisco …
Поиск файлов с помощью find
Хотя это, вероятно, не требуется в этом конкретном случае, найти, как правило, считается безопасным при прокладке трубопроводов в xargs . Однако вся логика, кажется, выходит из окна, когда я использую find -regex .
Однако я знаю, что могу найти эти файлы …
Вопросов
Я понимаю, что find -regex должен соответствовать возврату полного пути, но почему не find -regextype grep -regex «.*/cisco*» -print работает выше? Не следует .*/cisco* соответствует пути?
Я знаю, что я мог бы просто использовать find -path «*cisco*» для решения проблемы, но дело в том, чтобы понять, почему использование my -regex неверно.
Поиск с помощью ls : сначала сначала, ls | grep cisco ls | grep cisco немного многословный, поскольку cisco не является регулярным выражением. Пытаться:
Используя find : по тем же линиям, -regex переполняется простым статическим шаблоном. Как насчет:
Кавычки требуются, поэтому glob интерпретируется find , а не оболочкой. Кроме того, -print требуется для многих версий find , но является необязательным (и предикатом по умолчанию) для других (например, GNU find ). Не стесняйтесь добавлять его, если вам это нужно.
Если вам нужно найти «cisco» в полном пути, вы можете попробовать следующее:
что эквивалентно find | fgrep cisco find | fgrep cisco .
Использование find с регулярными выражениями : давайте сделаем это в любом случае, так как это то, что вы хотите. Бесстыдное копирование с GNU find manpage:
Это означает, что ваше регулярное выражение завернуто в невидимый ^. $ , поэтому он должен соответствовать каждому символу в полном пути файла. Итак, как сказал nwildner и otokan в комментариях, вы должны использовать что-то вроде:
И вам даже не нужен -regextype для чего-то такого простого.
Причина, по которой find -regex «.*/cisco*» не будет соответствовать никаким путям, например ./cisco-eem-tcl.rst или ./cisco_autonomous_to_lwap.rst выглядит следующим образом:
- .* соответствует чему угодно – любому персонажу, ноль или более раз
- / соответствует одной косой чертой – пока что так хорошо
- cisco* соответствует cisc , за которым следует любое количество o .
Помните, что оператор asterix * сдерживает повторение предыдущего элемента, который в этом случае равен o . Это означает, что мы не имеем ничего общего с этим последним компонентом шаблона, потому что это будет нечто вроде cisc , cisco , ciscoo , ciscooo … ad infinitum.
Если вам нужно выразить, что все может следовать за словом cisco , тогда используйте .* После этого:
Возможно, вам хотелось бы немного ограничивать результаты поиска, сопоставляя только rst файлы:
Тем не менее, выполнение простого совпадения в компоненте имени файла пути, таком как это, не требует выразительной мощности регулярных выражений, поэтому вы можете просто отлично использовать только -name с помощью glob для получения того же соответствия:
и для обработки этих совпадений с помощью xargs вы сделали бы что-то вроде этого:
Вы всегда должны помнить, что регулярные выражения и глобусы – это разные вещи синтаксически и семантически. Посмотрите, как man find и читают о параметрах -name и -regex , чтобы узнать больше.
Источник
Блог о системном администрировании. Статьи о Linux, Windows, СХД NetApp и виртуализации.
Доброго времени, гости!
В сегодняшней статье хочу коснуться такой огромной темы как Регулярные выражения. Думаю всем известно, что тема регексов (так регулярные выражения называются на сленге) — необъятна в объеме одного поста. Посему постараюсь кратко, но как можно понятней собрать в кучу свои мысли и донести их до Вас в своем блоге.
Начну с того, что существует несколько разновидностей регулярных выражений:
1. Традиционные регулярные выражения (они же основные, базовые и basic regular expressions (BRE))
- синтаксис данных выражений определен, как устаревший, но тем не менее до сих пор широко распространен и используется многими утилитами UNIX
- Основные регулярные выражения включают в себя следующие метасимволы (об их значениях ниже):
- .
- [ ]
- [^ ]
- ^
- $
- *
- \ < \>— первоначальный вариант для < >(в расширенных)
- \( \) — первоначальный вариант для ( ) (в расширенных)
- \n , где n — номер от 1 до 9
- Особенности использования данных метасимволов:
- Звёздочка должна следовать после выражения, соответствующего единичному символу. Пример: [xyz]* .
- Выражение \(блок\)* следует считать неправильным. В некоторых случаях оно соответствует нулю или более повторений строки блок . В других оно соответствует строке блок* .
- Внутри символьного класса специальные значения символов, в основном, игнорируются. Особые случаи:
- Чтобы добавить символ ^ в набор, его следует поместить туда не первым.
- Чтобы добавить символ — в набор, его следует поместить туда первым или последним. Например:
- шаблон DNS-имени, куда могут входить буквы, цифры, минус и точка-разделитель: [-0-9a-zA-Z.] ;
- любой символ, кроме минуса и цифры: [^-0-9] .
- Чтобы добавить символ [ или ] в набор, его следует поместить туда первым. Например:
- [][ab] соответствует ] , [ , a или b .
2. Расширенные регулярные выражения (они же extended regular expressions (ERE))
- Синтаксис данных выражений аналогичен синтаксису основных выражений, за исключением:
- Отменено использование обратной косой черты для метасимволов < >и ( ) .
- Обратная косая черта перед метасимволом отменяет его специальное значение.
- Отвергнута теоретически нерегулярная конструкция \n .
- Добавлены метасимволы + , ? , | .
3. Регулярные выражения, совместимые с Perl (они же Perl-compatible regular expressions (PCRE))
- имеют более богатый и в то же время предсказуемый синтаксис, чем даже POSIX ERE, поэтому часто используется приложениями.
Далее немного поговорим о синтаксисе регулярных выражений .
Регулярные выражения состоят из шаблонов, вернее сказать задают шаблон поиска. Шаблон состоит из правил поиска, которые составляются из символов и метасимволов.
Правила поиска определяются следующими операциями:
Перечисление |
Вертикальная черта (|) разделяет допустимые варианты, можно сказать — логическое ИЛИ. Например, «gray|grey» соответствует gray или grey.
Группировка или объединение ( )
Круглые скобки используются для определения области действия и приоритета операторов. Например, «gray|grey» и «gr(a|e)y» являются разными образцами, но они оба описывают множество, содержащее gray и grey.
Квантификация <> ? * +
Квантификатор после символа или группы определяет, сколько раз предшествующее выражение может встречаться.
общее выражение, повторений может быть от m до n включительно.
общее выражение, m и более повторений.
общее выражение, не более n повторений.
ровно n повторений.
Знак вопроса означает 0 или 1 раз, то же самое, что и . Например, «colou?r» соответствует и color, и colour.
Звёздочка означает 0, 1 или любое число раз ( ). Например, «go*gle» соответствует ggle, gogle, google и др.
Плюс означает хотя бы 1 раз ( ). Например, «go+gle» соответствует gogle, google и т. д. (но не ggle).
Конкретный синтаксис данных регулярных выражений зависит от реализации. (то есть в базовых регулярных выражениях символы — экранируются обратным слешем)
Метасимволы, говоря простым языком — это символы, которые не соответствуют своему реальному значению, то есть символ . (точка) — это не точка, а любой один символ, и т.п. прошу ознакомиться с метасимволами и их значениями:
. | соответствует одному любому символу |
[что-то] | Соответствует любому единичномусимволу из числа заключённых в скобки. При этом:Символ «-» интерпретируется буквально только в том случае, если он расположен непосредственно после открывающей или перед закрывающей скобкой: [abc-] или [-abc]. В противном случае, он обозначает интервал символов.Например, [abc] соответствует «a», «b» или «c». [a-z] соответствует буквам нижнего регистра латинского алфавита. Эти обозначения могут и сочетаться: [abcq-z] соответствует a, b, c, q, r, s, t, u, v, w, x, y, z.Чтобы установить соответствие символам «[» или «]», достаточно, чтобы закрывающая скобка была первым символом после открывающей: [][ab] соответствует «]», «[», «a» или «b».Если значение в квадратных скобах предварено символом ^, то значение выражения соответствует единичному символу из числа тех, которых нет в скобках. Например, [^abc] соответствует любому символу, кроме «a», «b» или «c». [^a-z] соответствует любому символу, кроме символов нижнего регистра в латинском алфавите. |
^ | Соответствует началу текста (или началу любой строки, если режим построчный). |
$ | Соответствует концу текста (или концу любой строки, если режим построчный). |
\(\) или ( ) | Объявляет «отмеченное подвыражение» (сгруппированное выражение), которое может быть использовано позже (см. следующий элемент: \n). «Отмеченное подвыражение» также является «блоком». В отличие от других операторов, этот (в традиционном синтаксисе) требует бэкслеша, в расширенном и Perl символ \ — не нужен. |
\n | Где n — это цифра от 1 до 9; соответствует n-му отмеченному подвыражению (например (abcd)\0, то есть символы abcd отмечены нулем). Эта конструкция теоретически нерегулярна, она не была принята в расширенном синтаксисе регулярных выражений. |
* |
. Выражение, заключённое в «\(» и «\)» и сопровождаемое «*», следует считать неправильным. В некоторых случаях, оно соответствует нулю или более вхождений строки, которая была заключена в скобки. В других, оно соответствует выражению, заключённому в скобки, учитывая символ «*». |
\<x,y\> | Соответствует последнему (предстоящему) блоку, встречающемуся не менее x и не более y раз. Например, «a\<3,5\>» соответствует «aaa», «aaaa» или «aaaaa». В отличие от других операторов, этот (в традиционном синтаксисе) требует бэкслеша. |
.* | Обозначение любого количества любых символов между двумя частями регулярного выражения. |
Метасимволы нам помогают использовать различные соответствия. Но как же представить метасимвол обычным символом, то есть символ [ (квадратная скобка) значением квадратной скобки? Просто:
- необходимо предварить (экранировать) метасимвол (. * + \ ? [ ] < >) обратным слешем. Например \. или\[
Для упрощения задания некоторых наборов символов, их объединили в т.н. классы и категории символов . POSIX стандартизовал объявление некоторых классов и категорий символов, как показано в следующей таблице:
POSIX класс | аналогично | обозначение |
[:upper:] | [A-Z] | символы верхнего регистра |
[:lower:] | [a-z] | символы нижнего регистра |
[:alpha:] | [A-Za-z] | символы верхнего и нижнего регистра |
[:alnum:] | [A-Za-z0-9] | цифры, символы верхнего и нижнего регистра |
[:digit:] | 8 | цифры |
[:xdigit:] | [0-9A-Fa-f] | шестнадцатеричные цифры |
[:punct:] | [. …] | знаки пунктуации |
[:blank:] | [ \t] | пробел и TAB |
[:space:] | [ \t\n\r\f\v] | символы пропуска |
[:cntrl:] | символы управления | |
[:graph:] | [^ \t\n\r\f\v] | символы печати |
[:print:] | [^\t\n\r\f\v] | символы печати и символы пропуска |
В regex есть такое понятие как:
Жадность regex
Постараюсь описать как можно понятней. Допустим, мы хотим найти все HTML теги в каком-то тексте. Локализовав задачу, мы хотим найти значения заключенные между , вместе с этими самыми скобками. Но мы знаем, что теги имеют разную длину и самих тегов, как минимум штук 50. Перечислять их все , заключив в метасимволы [] — задача слишком трудоемкая. Но мы знаем, что у нас есть выражение .* (точка звездочка), характеризующее любое число любых символов в строке. С помощью данного выражения мы попытаемся найти в тексте (
Итак, Как создать RAID уровня 10/50 на контроллере LSI MegaRAID (актуально и для: Intel SRCU42x, Intel SRCS16):
) все значения между . В результате, этому выражению будет соответствовать ВСЯ строка. почему, потому что регекс — ЖАДЕН и старается захватить ЛЮБОЕ ВСЕ количество символов между , соответственно вся строка, начиная p>Итак. и заканчивая .
> будет принадлежать данному правилу!
Надеюсь, на примере понятно что такое жадность. Чтобы избавиться от данной жадности, можно пойти по следующему пути:
- учесть символы, не соответствующие желаемому образцу (например: ]*> для вышеописанного случая)
- избавить от жадности, добавив определении квантификатора, как нежадного:
- *? — «не жадный» («ленивый») эквивалент *
- +? — «не жадный» («ленивый») эквивалент +
? — «не жадный» («ленивый») эквивалент
- .*? — «не жадный» («ленивый») эквивалент .*
Все вышенаписанное хочу дополнить синтаксисом расширенных регулярных выражений:
Регулярные выражения в POSIX аналогичны традиционному Unix-синтаксису, но с добавлением некоторых метасимволов:
Плюс указывает на то, что предыдущий символ или группа может повторяться один или несколько раз. В отличие от звёздочки, хотя бы одно повторение обязательно.
Знак вопроса делает предыдущий символ или группу необязательной. Другими словами, в соответствующей строке она может отсутствовать, либо присутствовать ровно один раз.
Вертикальная черта разделяет альтернативные варианты регулярных выражений. Один символ задаёт две альтернативы, но их может быть и больше, достаточно использовать больше вертикальных чёрточек. Необходимо помнить, что этот оператор использует максимально возможную часть выражения. По этой причине, оператор альтернативы чаще всего используется внутри скобок.
Также было отменено использование обратной косой черты: \ <…\>становится <…>и \(…\) становится (…).
В завершение поста, приведу некоторые примеры использования regex:
Источник