regexp

Жизнь заставила окунуться в регулярку, ну что же отправляюсь постигать дзен. Вообще нереально написать неправильное регулярное выражение, можно написать выражение которые будет находить не то что нужно:) Здесь больше рассматривается применение в Unixовом grepе, поэтому перловочники и прочие проходят мимо.
Если у кого есть дельные советы то прошу делиться.

Пару ключей grep :
-v отобразить то, что НЕ совпало с выражением(инверсия)
-o отобразить непосредственный результат, а не всю строку где есть совпадение
-i не учитывать регистр
-с отображает количество совпадений
-E расширенная версия grep
-P perloвая версия (PCRE- Perl-Compatible Regular Expressions)
-n номер строки где есть совпадение
-w только если выражение является словом(пробелы с двух сторон)
-x только если выражение полностью совпадает со строкой!(не совпадет, если в строке есть что-то еще кроме выражения)
-F быстрый grep, ищет только строки, никаких регулярок

При использовании grep обязательно регулярку писать в ‘ ‘ (одинарных кавычках), так вы сбережете нервы на отладке. И не нужно будет экранировать многие символы, будут нормально восприниматься пробелы!!
Используя “” двойные кавычки мы так же можем использовать переменные окружения.
Пример:

Устанавливаем значение переменной ololo = Hell 
% setenv ololo Hell
Выводим значение переменной
% echo $ololo
Hell
Используем переменную окружения в поиске
% cat test.txt | grep  "$ololo"
Hello! My name Alexey! Please visit my web site https://bos-info.com
Hello

В обычном grep нужно экранировать все метасимволы, в результате будет типа так \[Aa\] иначе скобки будут интерпретированы как обычные символы.

. – один любой символ
^ – начало строки
$ – конец строки
| – или 19|20 будет выбран или 19 или 20
+ – один или несколько символов или {1,}
* – любое количество совпадений, втч 0
? – 0 или 1 совпадение с шаблоном или можно записать {0,1}
{n} – количество совпадений с шаблоном
{n,m} – n совпадений с шаблоном, но не более m
{n,} – не менее n совпадений с шаблоном
\ – экранирование символа(например, чтобы найти просто точку нужно использовать экранирование)
Поскольку * и ? жадные кванторы и ищут самое длинное вхождение до конца строки!, то есть ленивые квантаторы, которые ищут короткое вхождение первое совпадение.
*? +? {n,}?
\(regexp\)\{1,3\} – действия будут применяться ко всему выражению в скобках
Также можно использовать ссылку назад, для нахождения нескольких совпадающих слов, например:
\(regexp\).*?\1 \1 – и есть ссылка назад

Txt file:
The red dog fetches the green ball.
The green dog fetches the blue ball.
The blue dog fetches the blue ball.
grep -E '(red|green|blue).*\1' filename

В результате получим 3ю строку которая содержит повторяющиеся слова
Ссылки назад работают только если, выражение на которое они ссылаются является подвыражением и потому заключено в скобки! Нумерация подвыражений может начинаться с нуля.

Пробельные символы
\t – символ табуляции
\n – перевод строки в win (\r\n)
\f – перевод страницы
\v – вертикальная табуляция
\s – [\t\n\r\f\v]
\S – [^\t\n\r\f\v]

\d – цифры [0-9]
\D – НЕ цифры [^0-9]
\w – [A-Za-z0-9_]
\W – [^A-Za-z0-9_]
\< - начало слова \> – конец слова
\b – граница слова
\B – не граница слова

[Aa] -любой из символов в скобках
[A-Z] с помощью – задаем последовательсность символов
[^A-Z] с помощью ^ операция НЕ, будут найдены значения которые не совпали с теми, что в скобках

POSIX использовать обязательно как показано в двойных скобках(не экранировать)
[[:alnum:]] – [A-Za-z0-9]
[[:alpha:]] – [a-zA-Z]
[[:blank:]] – [\t ] табуляция или пробел
[[:cntrl:]] – ASCII коды 0-31 127
[[:digit:]] – [0-9]
[[:graph:]] – любой печатный символ, пробел исключен
[[:lower:]] – [a-z]
[[:print:]] – любой печатный символ, втч пробел
[[:punct:]] – любой символ не входящий в [[:alnum:]] и [[:cntrl:]]
[[:space:]] – [\f\n\r\t\v ]
[[:upper:]] – [A-Z]
[[:xdigit:]] – [A-Fa-f0-9] hex числа

для поиска символа { в egrep нужно его экранировать достаточно интересным способом [{]

Сравнение синтаксиса обычного и расширенного grep
Основной Расширенный
‘\(red\)’ ‘(red)’
‘a\{1,3\}’ ‘a{1,3}’
‘behaviou\?r’ ‘behaviou?r’
‘pattern\+’ ‘pattern+’

Не реализовано в grep, или я не нашел!

.+(?=regexp2) – просмотр вперед! ищет строку, но не включает в вывод regexp2
(?<=regexp1).+ - просмотр назад! ищет строку, но не включает в вывод regexp1 .+(?!regexp2) - отрицательный просмотр вперед! ищет строку которая не соответствует шаблону и не включает в вывод regexp2 (? %grep -o 'C..' test.txt Cat

2. Включаем расширенный режим, выводим только результаты, ищем выражение в начале строки начинающееся на Н и содержащее потом от 1 до 4 символов, потом любой печатный символ, кроме пробела и дальше собственно пробел.

%grep -Eo '^H.{1,4}\>[[:graph:]][[:space:]]' test.txt
Hello!

3. Вытянуть LA из аптайма

%uptime | grep -o 'load.*'
load averages: 0.09, 0.06, 0.07

4. Вытянуть из нетстата маршрут по умолчанию

%netstat -nr | grep default | grep -o '\([[:digit:]]\{1,3\}\.\)\{3\}[[:digit:]]\{1,3\}'
172.16.0.1

P.S.
1. IPv4 адрес
$ grep -E ‘\b((25[0-5]|2[0-4][0-9]|[01]?
[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|
[01]?[0-9][0-9]?)\b’ ololo.txt
2. MAC адрес
$ grep -Ei ‘\b[[:xdigit:]]{2}(:[[:xdigit:]]{2}){5}\b’ ololo.txt

Следующие на очереди sed и awk 🙂

Залишити відповідь

Ваша e-mail адреса не оприлюднюватиметься. Обов’язкові поля позначені *