Жизнь заставила окунуться в регулярку, ну что же отправляюсь постигать дзен. Вообще нереально написать неправильное регулярное выражение, можно написать выражение которые будет находить не то что нужно:) Здесь больше рассматривается применение в 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 🙂