Регекс регулярні вирази bash. П'ять прикладів використання grep. Синтаксичні аспекти мови "Баша"

Про цього самовчителя

Ласкаво просимо в «Ази адміністрування», друге з чотирьох посібників, розроблених, щоб підготувати вас до іспиту 101 в Linux Professional Institute. У цій частині ми розглянемо використання регулярних виразів для пошуку тексту у файлах за шаблонами. Потім ви познайомитеся зі «Стандартом ієрархії файлової системи» (Filesystem Hierarchy Standard або скор. FHS), також ми покажемо вам як знаходити потрібні файли у вашій системі. Після чого, ви дізнаєтеся як отримати повний контроль над процесами в Linux, запускаючи їх у фоновому режимі, переглядаючи список процесів, від'єднуючи їх від терміналу та багато іншого. Далі піде швидке введення в конвеєри, перенаправлення та команди обробки тексту. І нарешті ми познайомимо вас з модулями ядра Linux.

Зокрема ця частина самовчителя (Частина 2) ідеальна для тих, хто вже має непогані базові знання bash і хоче отримати якісне введення до основних завдань адміністрування Linux. Якщо в Linux ви новачок, ми рекомендуємо вам спершу закінчити першу частину цієї серії практичних посібників. Для деяких, більша частина даного матеріалу буде новою, досвідченіші ж користувачі Linux можуть вважати його відмінним засобом підбити підсумок своїм базовим навичкам адміністрування.



Якщо ви вивчали перший випуск цього самовчителя з метою, відмінною від підготовки до екзамену LPI, то вам, можливо, не потрібно перечитувати цей випуск. Однак, якщо ви плануєте складати іспит, то вам настійно рекомендуються перечитати цю, переглянуту версію самовчителя.

Регулярні вирази

Що таке «регулярний вираз»?

Регулярне вираз (по англ. regular expression, скор. «regexp» або «regex», на батьківщині іноді називається «регулярка» - прим. пер.) - це особливий синтаксис, що використовується для опису текстових шаблонів. У Linux-системах регулярні висловлювання широко використовуються для пошуку в тексті за шаблоном, а також для операцій пошуку та заміни текстових потоків.

У порівнянні з глобінгом

Як тільки ми почнемо розглядати регулярні вирази, можливо, зверніть увагу, що їх синтаксис дуже схожий на синтаксис підстановки імен файлів (globbing), який ми розглядали в першій частині. Однак, не варто помилятися, ця схожість дуже поверхова. Регулярні вирази та глоббінг-шаблони, навіть коли вони виглядають схоже, принципово різні речі.

Просте підрядження

Після цього застереження, давайте розглянемо найголовніше в регулярних виразах, найпростіший підрядок. Для цього ми скористаємося "grep", командою, яка сканує вміст файлу відповідно до заданого регулярного виразу. grep виводить кожен рядок, який збігається з регулярним виразом, ігноруючи інші:

$ grep bash /etc/passwd
operator:x:11:0:operator:/root:/bin/bash root:x:0:0::/root:/bin/bash ftp:x:40:1::/home/ftp:/bin/ bash

Вище перший параметр для grep, це regex; другий – ім'я файлу. grep зчитував кожний рядок з /etc/passwdі прикладав на неї просте regex-підрядок «bash» у пошуках збігу. Якщо збіг виявлялося, то grep виводив весь рядок цілком; в іншому випадку рядок ігнорувався.

Розуміння простого підрядку

В загальному випадку, якщо ви шукайте підрядок, ви просто можете вказати його буквально, не використовуючи будь-яких спеціальних символів. Вам знадобиться особливо подбати, тільки якщо ваше підрядження містить +, ., *, [, ] або \, в цьому випадку ці символи повинні бути екрановані зворотним слешем, а підрядок полягати в лапки. Ось кілька прикладів регулярних виразів у вигляді простого підрядку:

  • /tmp (пошук рядка /tmp)
  • "\" (пошук рядка)
  • "\*funny\*" (пошук рядка *funny*)
  • "ld\.so" (пошук рядка ld.so)

Метасимволи

За допомогою регулярних виразів використовуючи метасимволи можна здійснювати набагато складніший пошук, ніж у прикладах, які нещодавно розглядали. Один із таких метасимволів "." (точка), що збігається з будь-яким одиничним символом:

$ grep dev.sda /etc/fstab
/dev/sda3 / reiserfs noatime,ro 1 1 /dev/sda1 /boot reiserfs noauto,noatime,notail 1 2 /dev/sda2 swap swap sw 0 0 #/dev/sda4 /mnt/extra reiserfs noatime,rw 1

У цьому прикладі текст dev.sda не з'являється буквально в жодній з рядків з /etc/fstab. Однак, grep сканує його не буквально за рядком dev.sda, а за шаблоном dev.sda. Запам'ятайте, що "." буде відповідати будь-якому одиничному символу. Як ви бачите, метасимвол "." функціонально еквівалентний тому, як працює метасимвол "?" у glob-підстановках.

Використання

Якщо ми хочемо задати символ конкретніше, ніж це робить ".", то можемо використовувати [і] (квадратні дужки), щоб вказати підмножину символів для порівняння:

$ grep dev.sda /etc/fstab
/dev/sda1 /boot reiserfs noauto,noatime,notail 1 2 /dev/sda2 swap swap sw 0 0

Як ви помітили, зокрема, ця синтаксична конструкція працює ідентично конструкції "" при glob-підстановці імен файлів. Знову ж таки, в цьому полягає одна з неоднозначностей у вивченні регулярних виразів: синтаксис схожий, але не ідентичний синтаксису glob-підстановок, що збиває з пантелику.

Використання [^]

Ви можете звернути значення квадратних дужок помістивши ^ одразу після [. У цьому випадку дужки відповідатимуть будь-якому символу, який не перерахований всередині них. І знову, зауважте, що [^] ми використовуємо з регулярними виразами, а [!] з glob:

$ grep dev.hda[^12] /etc/fstab
/dev/hda3 / reiserfs noatime,ro 1 1 #/dev/hda4 /mnt/extra reiserfs noatime,rw 1 1

Відмінний синтаксис

Дуже важливо відзначити, що синтаксис усередині квадратних дужок докорінно відрізняється від решти регулярного виразу. Наприклад, якщо ви помістите "." всередину квадратних дужок, це дозволить квадратним дужкам збігатися з "." буквально, як і 1 і 2 у прикладі вище. Для порівняння, "." поміщена поза квадратними дужками, буде інтерпретована як метасимвол, якщо не приставити "\". Ми можемо отримати вигоду з даного факту для виведення рядків з /etc/fstab, які містять рядок dev.sda, як він записаний:

$ grep dev[.]sda /etc/fstab

Також, ми могли б набрати:

$ grep "dev\.sda" /etc/fstab

Ці регулярні вирази ймовірно не задовольняють жодному рядку з вашого /etc/fstabфайлу.

Матасимвол *

Деякі метасимволи власними силами не відповідають нічому, але змінюють значення попереднього символу. Один із таких символів, це * (зірочка), який використовується для зіставлення нульового або більшого числа повторень попереднього символу. Зауважте, це означає, що * має інше значення в регулярках, ніж у глоббінгу. Ось кілька прикладів, і зверніть особливу увагу на ті випадки, де зіставлення регулярних виразів відрізняється від glob-підстановок:

  • ab*cзбігається з «abbbbc», але не з «abqc» (у разі glob-підстановки обидві рядки будуть задовольняти шаблону. Ви вже зрозуміли чому?)
  • ab*cзбігається з «abc», але не з «abbqbbc» (знову ж таки, при glob-підстановці, шаблон зіставимо з обома рядками)
  • ab*cзбігається з "ac", але не з "cba" (у разі глоббінгу, ні "ac", ні "cba" не задовольняють шаблону)
  • b*eзбігається з «bqe» та з «be» (glob-підстановці задовольняє «bqe», але не «be»)
  • b*eзбігається з «bccqqe», але не з «bccc» (при глоббінгу шаблон так само збігається з першим, але не з другим)
  • b*eзбігається з "bqqcce", але не з "cqe" (так само і при glob-підстановці)
  • b*eзадовольняє «bbbeee» (але не у разі глоббінгу)
  • .* зіставимо з будь-яким рядком (glob-підстановці задовольняють тільки рядки, що починаються з ".")
  • foo.збігається з будь-яким підрядком, що починається з «foo» (у разі glob-підстановки цей шаблон буде збігатися з рядками, що починаються з чотирьох символів «foo.»)

Отже, повторимо для закріплення: рядок «ac» підходить під регулярне вираження «ab * c» тому, що зірочка також дозволяє повторення попереднього виразу (b) нуль разів. І знову, цінно відзначити собі, що метасимвол * в регулярках інтерпретується зовсім інакше, ніж символ * в glob-основах.

Початок та кінець рядка

Останні метасимволи, що ми детально розглянемо, це ^ і $, які використовуються для зіставлення початку та кінця рядка, відповідно. Скориставшись на початку вашого regex, ви «прикріпите» ваш шаблон до початку рядка. У наступному прикладі ми використовуємо регулярний вираз ^#, який задовольняє будь-якому рядку, що починається з символу #:

$ grep ^# /etc/fstab

#

Повнорядне регулювання

^ і $ можна комбінувати, для порівнянь з усім рядком цілком. Наприклад, нижченаведене регулювання буде відповідати рядкам, що починаються з символу #, а символом ".", що закінчується, при довільній кількості символів між ними:

$ grep "^#.*\.$" /etc/fstab
# /etc/fstab: static file system information.

У прикладі вище ми уклали наш регулярний вираз в одиночні лапки, щоб запобігти інтерпретування символу $ командною оболонкою. Без одиночних лапок $ зник би з нашого регулювання ще навіть до того, як grep міг його побачити.

Про авторів

Daniel Robbins

Деніель Роббінс - засновник спільноти Gentoo та творець операційної системи Gentoo Linux. Деніель проживає в Нью-Мехіко зі своєю дружиною Мері та двома енергійними дочками. Він також засновник і глава Funtoo, написав безліч технічних статей для IBM developerWorks, Intel Developer Services та C/C++ Users Journal.

Chris Houser

Кріс Хаусер був прихильником UNIX з 1994 року, коли приєднався до команди адміністраторів університету Тейлора (Індіана, США), де здобув ступінь бакалавра у комп'ютерних науках та математиці. Після цього він працював у багатьох областях, включаючи веб-додатки, редагування відео, драйвера для UNIX і криптографічний захист. На даний момент працює в Sentry Data Systems. Кріс також зробив внесок у безліч вільних проектів, таких як Gentoo Linux та Clojure, став співавтором книги The Joy of Clojure.

Aron Griffis

Ейрон Гріффіс живе на території Бостона, де провів останнє десятиліття працюючи в Hewlett-Packard над такими проектами, як мережеві UNIX-драйвера для Tru64, сертифікація безпеки Linux, Xen і KVM віртуалізація, і останнє - платформа HP ePrint. У вільний від програмування час Ейрон вважає за краще роздумувати над проблемами програмування катаючись на своєму велосипеді, жонглюючи бітами, або вболіваючи за бостонську професійну бейсбольну команду «Червоні Шкарпетки».

grep розшифровується як 'global regular expression printer'. grep відрізає потрібні вам рядки з текстових файлів, які містять вказаний користувачем текст.

grep може бути використаний двома шляхами - сам собою або в комбінації з потоками.

grep дуже великий у функціональності, за рахунок великої кількості підтримуваних ним опцій, таких як: пошук з використанням рядкового шаблону або RegExp регулярних виразів шаблону або perl based регулярних виразів і т.д.

Через його різні функціональні можливості інструмент grep має безліч варіантів, включаючи egrep (Extended GREP), fgrep (Fixed GREP), pgrep (Process GREP), rgrep (рекурсивний GREP)і т.д. Але ці варіанти мають незначні відмінності від оригінального grep.

Параметри grep

$ grep -V grep (GNU grep) 2.10 Copyright (C) 2011 Free Software Foundation, Inc. Ліцензія GPLv3+

Існують модифікації утиліти grep: egrep (з обробкою розширених регулярних виразів), fgrep (трактує символи $*^|()\ як літерали, тобто буквально), rgrep (з включеним рекурсивним пошуком).

    egrep те саме що grep -E

    fgrep те саме що grep -F

    rgrep те саме що grep -r

    grep [-b] [-c] [-i] [-l] [-n] [-s] [-v] обмежений_регулярний_вираз_BRE [файл …]

Команда grep зіставляє рядки вихідних файлів із шаблоном, заданим обмеженим_регулярним_виразом. Якщо файли не вказані, використовується стандартне введення. Зазвичай, кожен успішно зіставлений рядок копіюється на стандартний висновок; якщо вихідних файлів кілька, перед знайденим рядком видається ім'я файлу. У grep використовується компактний недетермінований алгоритм. Як шаблони сприймаються обмежені регулярні вирази (вирази, що мають своїми значеннями ланцюжки символів, і використовують обмежений набір алфавітно-цифрових і спеціальних символів). Вони мають той самий сенс, що й регулярні вирази у ed.

Для екранування символів $, *, , ^, |, (), і від інтерпретації shell"ом найпростіше укладати обмежене_регулярне_вираження в одинарні лапки.

Опції:

B Попереджає кожен рядок номером блоку, в якому його було знайдено. Це може стати в нагоді при пошуку блоків за контекстом (блоки нумеруються з 0). -c Видає лише кількість рядків, що містять зразок. -h Запобігає видачу імені файлу, що містить рядок, що зіставився, перед власне рядком. Використовується при пошуку кількох файлів. -i Ігнорує регістр символів під час порівняння. -l Видає тільки імена файлів, що містять рядки, що зіставилися, по одному в рядку. Якщо зразок знайдено у кількох рядках файлу, ім'я файлу не повторюється. -n Видає перед кожним рядком її номер у файлі (рядки нумеруються з 1). -s Пригнічує видачу повідомлень про не існуючі або недоступні для читання файли. -v Видає всі рядки, за винятком зразків. -w Шукає вираз як слово, ніби воно було оточене метасимволами \< и \>.

grep --help

Використання: grep [ПАРАМЕТР]… ШАБЛОН [ФАЙЛ]… Пошук ШАБЛОНУ в кожному ФАЙЛІ або стандартному введенні. За умовчанням, ШАБЛОН є простим регулярним виразом (BRE). Приклад: grep -i "hello world" menu.h main.c Вибір типу регулярного виразу та його інтерпретація: -E, --extended-regexp ШАБЛОН - розширений регулярний вираз (ERE) -F, --fixed-regexp ШАБЛОН - рядки фіксованої довжини, розділені символом нового рядка -G, --basic-regexp ШАБЛОН - простий регулярний вираз (BRE) -P, --perl-regexp ШАБЛОН - регулярний вираз мови Perl -e, --regexp=ШАБЛОН використовувати ШАБЛОН для пошуку - f, --file=ФАЙЛ брати ШАБЛОН з ФАЙЛу -i, --ignore-case ігнорувати відмінність регістру -w, --word-regexp ШАБЛОН повинен підходити до всіх слів -x, --line-regexp ШАБЛОН повинен підходити до всього рядка -z, --null-data рядки поділяються байтом з нульовим значенням, а не символом кінця рядка. -version надрукувати інформацію про версію та вийти --help показати цю довідку та закінчити роботу --mmap для зворотної сумісності, ігнорується Управління висновком: -m, --max-count=КІСЛО зупинитися після вказаного ЧИСЛА збігів -b, --byte- offset друкувати разом з вихідними рядками усунення в байтах -n, --line-number друкувати номер рядка разом з вихідними рядками --line-buffered скидати буфер після кожного рядка -H, --with-filename друкувати ім'я файлу для кожного збігу -h , --no-filename не починати виведення з імені файлу --label=МІТКА використовувати МІТКУ як ім'я файлу для стандартного введення -o, --only-matching показувати тільки частину рядка, що збігається з ШАБЛОНОМ -q, --quiet, - -silent придушувати весь звичайний висновок --binary-files=ТІП вважати, що двійковий файл має тип: binary, text або without-match. -a, --text те саме що і --binary-files=text -I те саме, що і --binary-files=without-match -d, --directories=ДІЙ як обробляти каталоги ДІЯ може бути read (читати ), recurse (рекурсивно) чи skip (пропускати). -D, --devices=ДІЙ як обробляти пристрої, FIFO та сокети ДІЯ може бути read або skip -R, -r, --recursive те ж, що і --directories=recurse --include=Ф_ШАБЛОН обробити тільки файли, що підпадають під Ф_ШАБЛОН --exclude=Ф_ШАБЛОН пропустити файли та каталоги, що підпадають під Ф_ШАБЛОН --exclude-from=ФАЙЛ пропустити файли, що підпадають під шаблон файлів із ФАЙЛА --exclude-dir=ШАБЛОН каталоги, що підпадають під ШАБЛОН, будуть пропущені -L, - -files-without-match друкувати тільки імена ФАЙЛІВ без збігів -l, --files-with-matches друкувати тільки імена ФАЙЛІВ із збігами -c, --count друкувати тільки кількість рядків, що збігаються на ФАЙЛ -T, --initial-tab вирівнювати табуляцією (якщо потрібно) -Z, --null друкувати байт 0 після імені ФАЙЛА Управління контекстом: -B, --before-context=ЧІС друкувати ЧИСЛО рядків попереднього контексту -A, --after-context=ЧИС друкувати ЧИСЛО рядків наступного контексту -C, --context[=ЧИС] друкувати ЧИСЛО рядків контексту -ЧИСЛО те ж, що і --context=КІЛЬКІСТЬ --color[=КОЛИ], --colour[=КОЛИ] використовувати маркери для відмінності збігаються рядків; КОЛИ може бути always (завжди), never (ніколи) або auto (автоматично) -U, --binary не видаляти символи CR в кінці рядка (MSDOS) -u, --unix-byte-offsets видавати зміщення, начебто ні CR-ів (MSDOS) Замість "egrep" передбачається запуск "grep-E". Замість "fgrep" передбачається "grep-F". Запуск під іменами "egrep" або "fgrep" краще не виконувати. Коли не заданий ФАЙЛ, або коли ФАЙЛ це - то читається стандартне введення. Якщо вказано менше, ніж два файли, передбачає -h. При знаходженні збігів кодом завершення програми буде 0 і 1, якщо ні. При виникненні помилок, або якщо не вказано параметр -q, кодом завершення буде 2. Про помилки повідомляйте за адресою Про помилки у перекладі повідомляйте за адресою Домашня сторінка GNU Grep: Довідка щодо роботи з програмами GNU:

Одна з найкорисніших та багатофункціональних команд у терміналі Linux – команда «grep». Назва являє собою акронім англійської фрази "search Globally for lines matching the Regular Expression, and Print them" (шукати скрізь відповідні регулярні вирази рядки і виводити їх). Команда «grep» переглядає вхідний потік послідовно, рядок за рядком, у пошуках збігів та виводить (відфільтровує) лише ті рядки, які містять текст, що збігається із заданим шаблоном – регулярним виразом.

Регулярні вирази - спеціальна формальна мова пошуку та здійснення маніпуляцій з підрядками у тексті, заснована на використанні метасимволів. Наразі вже практично всі сучасні мови програмування мають вбудовану підтримку регулярних виразів для обробки текстів, проте історично популяризації даного підходу багато в чому сприяв саме світ UNIX і зокрема ідеї, закладені в команди grep, sed та ін. Філософія все є файл » повністю пронизує UNIX і володіння інструментами для роботи з текстовими файлами є одним із обов'язкових навичок кожного користувача Linux.

ЗРАЗОК

GIST | Найпростіший пошук усіх рядків, у яких є текст "Adams". При оформленні цього та наступних прикладів дотримуватимемося наступного порядку: зверху параметри командного рядка, внизу стандартні потоки зліва введення stdin і справа виведення stdout .

Команда «grep» має багато опцій, які можна вказати при запуску. За допомогою цих опцій можна робити багато корисних речей і при цьому в принципі навіть не обов'язково добре розумітися на синтаксисі регулярних виразів.

ОПЦІЇ

Почнемо з того, що «grep» вміє не тільки фільтрувати стандартне введення stdin , але й здійснювати пошук файлів. За умовчанням «grep» шукатиме лише у файлах, що знаходяться в поточному каталозі, проте за допомогою дуже корисної опції --recursive можна сказати команді «grep» шукати рекурсивно починаючи із заданої директорії.

GIST | За замовчуванням команда grep чутлива до регістру. Наступний приклад показує як можна шукати і при цьому не враховувати регістр, наприклад «Adams» і «adams» одне й те саме:

Ignore-case "adams"

George Washington, 1789-1797 John Adams, 1797-1801 Thomas Jefferson, 1801-1809 John Adams, 1797-1801

GIST | Пошук навпаки (іноді говорять інвертний пошук), тобто будуть виведені всі рядки, крім тих, що мають входження вказаного шаблону:

Invert-match "Adams"

George Washington, 1789-1797 John Adams, 1797-1801 Thomas Jefferson, 1801-1809 George Washington, 1789-1797 Thomas Jefferson, 1801-1809

GIST | Опції звичайно можна і потрібно комбінувати один з одним. Наприклад, пошук навпаки з виведенням порядкових номерів рядків з входженнями:

Line-number --invert-match "Adams"

George Washington, 1789-1797 John Adams, 1797-1801 Thomas Jefferson, 1801-1809 1: George Washington, 1789-1797 3: Thomas Jefferson, 1801-1809

GIST | Забарвлення. Іноді зручно, коли слово, яке ми шукаємо, підсвічується кольором. Все це вже є в grep, залишається тільки включити:

Line-number --color=always "Adams"

George Washington, 1789-1797 John Adams, 1797-1801 Thomas Jefferson, 1801-1809 2: John Adams, 1797-1801

GIST | Ми хочемо вибрати всі помилки з лог файлу, але знаємо що в наступному стіпку після помилки може бути корисна інформація, тоді зручно вивести кілька рядків з контексту. За умовчанням «grep» виводить лише рядок, у якому було знайдено збіг, але є кілька опцій, що дозволяють змусити «grep» виводити більше. Для виведення кількох рядків (у нашому випадку двох) після входження:

Color=always -A2 "Adams"

George Washington, 1789-1797 John Adams, 1797-1801 Thomas Jefferson, 1801-1809 James Madison, 1809-1817 James Monroe, 1817-1825 John Adams, 1797-1801

GIST | Аналогічно для додаткового виведення кількох рядків перед входженням:

Color=always -B2 "James"

George Washington, 1789-1797 John Adams, 1797-1801 Thomas Jefferson, 1801-180 , 1817-1825

GIST | Однак найчастіше потрібно виводити симетричний контекст, для цього є ще більш скорочений запис. Виведемо по два рядки як зверху так і знизу від входження:

Color=always -C2 "James"

George Washington, 1789-1797 John Adams, 1797-1801 Thomas Jefferson, 1801-1809 James Madison, 1809-1817 James Monroe, 1817-1825 John Quincy Adams, 1825-1829 Andrew Jackson1, 18 John Adams, 1797-1801 Thomas Jefferson, 1801-1809 James Madison, 1809-1817 James Monroe, 1817-1825 John Quincy Adams, 1825-1829 Andrew Jackson, 1829-1837

GIST | Коли Ви шукаєте qwe , то за умовчанням «grep» виводитиме також qwe123 , 345qwerty тощо комбінації. Знайдемо тільки ті рядки, які вимикають саме все слово:

Word-regexp --color=always "John"

John Fitzgerald Kennedy, 1961-1963, Lyndon Baines Johnson, 1963-1969.

GIST | Ну і насамкінець якщо Ви просто хочете знати кількість рядків із збігами одним одниною, але при цьому не виводити більше нічого:

Count --color=always "John"

John Fitzgerald Kennedy, 1961-1963 Lyndon Baines Johnson, 1963-1969 Richard Milhous Nixon, 1969-1974 2

Варто відзначити, що у більшості опцій є двійник, наприклад --ignore-case можна привести до більш короткого вигляду -i і т.д.

БАЗОВІ РЕГУЛЯРНІ ВИРАЗИ

Усі регулярні вирази складаються з двох типів символів: стандартних текстових символів, які називаються літералами, та спеціальних символів, званих метасимволами. У попередніх прикладах пошук здійснювався за літералами (точний збіг за літерами), але далі буде набагато цікавіше. Ласкаво просимо у світ регулярних виразів!

Знак каретки ^ і долара $ мають у регулярному вираженні особливий зміст. Їх називають "якорями" (anchor). Якорі – це спеціальні символи, які вказують місцезнаходження у рядку необхідного збігу. Коли пошук доходить до якоря, він перевіряє, чи є відповідність, і якщо є – продовжує йти за шаблоном, не додаючи нічого до результату.

GIST | Якір каретка використовують для того, щоб вказати, що регулярний вираз необхідно перевірити саме з початку рядка:

Color=always "^J"

George Washington, 1789-1797 John Adams, 1797-1801 Thomas Jefferson, 1801-1809 John Adams, 1797-1801

GIST | Аналогічно якір долар варто використовувати в кінці шаблону, щоб вказати, що збіг дійсно тільки якщо шуканий рядок символів знаходиться в кінці текстового рядка і ніяк інакше:

Color=always "9$"

George Washington, 1789-1797 John Adams, 1797-1801 Thomas Jefferson, 1801-1809 Thomas Jefferson, 1801-1809

GIST | Будь-який символ. Символ точки використовується в регулярних виразах для того, щоб позначити, що в зазначеному місці може бути абсолютно будь-який символ:

Color=always "0.$"

GIST | Екранування. Якщо потрібно знайти саме символ крапка, тоді екранування допоможе. Знак екранування (як правило це зворотний сліш), що передує символу на кшталт точки, перетворює метасимвол на літерал:

Color=always "\."

George Washington. 1789-1797 John Adams, 1797-1801 Thomas Jefferson, 1801-1809 George Washington. 1789-1797

GIST | Класи символи. У регулярних виразах можна використовувати діапазони та класи символів. Для цього при складанні шаблону використовуються квадратні дужки. Помістивши групу символів (включаючи символи, які в іншому випадку були б витлумачені як метасимволи) у квадратні дужки, можна вказати, що в цій позиції може бути будь-який із взятих у дужки символів:

Color=always "0"

George Washington, 1789-1797 John Adams, 1797-1801 Thomas Jefferson, 1801-1809 John Adams, 1797-1801 Thomas Jefferson, 1801-1809

GIST | Діапазон. Це два символи, розділені дефісом, наприклад, 0-9 (десяткові цифри) або 0-9a-fA-F (шістнадцяткові цифри):

Color=always ""

George Washington, ??? John Adams, 1797-1801 Thomas Jefferson, 1801-1809 John Adams, 1797-1801 Thomas Jefferson, 1801-1809

GIST | Заперечення. Якщо першим символом виразу у квадратних дужках є каретка, інші символи приймаються як набір символів, які мають бути присутнім у заданої позиції регулярного выражения:

Color=always "[^7]$"

George Washington, 1789-1797 John Adams, 1797-1801 Thomas Jefferson, 1801-1809 John Adams, 1797-1801 Thomas Jefferson, 1801-1809

GIST | Класи символів POSIX Існує певний набір вже заздалегідь заготовлених класів символів, які Ви можете використовувати у регулярних виразах. Їх там з десяток, досить швидко переглянути мануал, щоб зрозуміти призначення кожного. Наприклад, відфільтруємо тільки шістнадцяткові цифри:

Color=always "^[[:xdigit:]]*$"

4.2 42 42abc 42 42abc

GIST | Повторення (0 або більше разів). Одним із найчастіше використовуваних метасимволів є символ зірочка, що означає «повторити попередній символ або вираз нуль або більше разів»:

Color=always "^*$"

George Washington, ??? John Adams, 1797-1801 Thomas Jefferson, 1801-1809 George Washington, ???

Розрізняють базові регулярні вирази BRE (basic regular expressions) та розширені ERE (extended regular expressions). У BRE розпізнаються такі метасимволи ^$. * та всі інші символи розцінюються як літерали. У ERE додані такі метасимволи () ( ) ? + | та пов'язані з ними функції. Ну а щоб усіх остаточно заплутати в «grep» придумали таку штуку – символи () ( ) в BRE обробляються як метасимволи, якщо вони екрановані зворотним слешем, в той час як в ERE постановка перед будь-якими метасимволами зворотного слеша призводить до того, що вони трактуються як літерали.

РОЗШИРЕНІ РЕГУЛЯРНІ ВИРАЗИ

GIST | Диз'юнкція. Подібно до того, як квадратні дужки задають різні можливі варіанти збігу одного символу, диз'юнкція дозволяє вказати альтернативні збіги для рядків символів або виразів. Для позначення диз'юнкції використовується символ вертикальної межі:

Extended-regexp --color=always "George|John"

George Washington, 1789-1797 John Adams, 1797-1801 Thomas Jefferson, 1801-1809 George Washington, 1789-1797 John Adams, 1797-1801

GIST | Збіг нуль або один раз. У розширених регулярних виразах існують кілька додаткових метасимволів, що вказують частоту повторення символу або виразу (подібно до того, як метасимвол зірочка вказує на збіги 0 або більше разів). Один із таких метасимволів це знак питання, який робить попередній символ або вираз, по суті, необов'язковим:

Extended-regexp --color=always "^(Andrew)?John"

John Adams, 1797-1801 Andrew Johnson, 1865-1869 Lyndon Baines Johnson, 1963-1969 John Adams, 1797-1801 Andrew Johnson, 1865-1869

GIST | Збіг один чи більше разів. Для цього передбачено метасимвол як знак плюс. Він працює майже як символ зірочка, за винятком того, що вираз повинен збігтися хоча б один раз:

Extended-regexp --color=always "^[[:alpha:] ]+$"

John Adams Andrew Johnson, 1865-1869 Lyndon Baines Johnson, 1963-1969 John Adams

GIST | Збіг вказана кількість разів. Для цього можна використовувати фігурні дужки. Ці метасимволи використовуються для вказівки точної кількості, діапазону, а також верхньої та нижньої межі кількості збігів виразу:

Extended-regexp --color=always "(1,3)\.(1,3)\.(1,3)\.(1,3)"

42 127.0.0.1 127.0.0.1

Команда grep настільки корисна, багатофункціональна і проста у вживанні, що одного разу познайомившись з нею, неможливо уявити собі роботу без неї.

Регулярні вирази - це дуже потужний інструмент для пошуку тексту за шаблоном, обробкою та зміною рядків, який можна застосовувати для вирішення безлічі завдань. Ось основні з них:

  • Перевірка введення тексту;
  • Пошук та заміна тексту у файлі;
  • Пакетне перейменування файлів;
  • Взаємодія із сервісами, такими як Apache;
  • Перевірка рядка на відповідність шаблону.

Це далеко не повний список, регулярні висловлювання дозволяють робити набагато більше. Але для нових користувачів вони можуть здатися надто складними, оскільки для їхнього формування використовується спеціальна мова. Але враховуючи можливості, регулярні вирази Linux повинен знати і вміти використовувати кожен системний адміністратор.

У цій статті ми розглянемо регулярні вирази bash для початківців, щоб ви змогли розібратися з усіма можливостями цього інструменту.

У регулярних виразах можуть використовуватися два типи символів:

  • звичайні літери;
  • метасимволи.

Звичайні символи - це літери, цифри та розділові знаки, з яких складаються будь-які рядки. Всі тексти складаються з літер і ви можете використовувати їх у регулярних виразах для пошуку потрібної позиції у тексті.

Метасимволи – це дещо інше, саме вони дають силу регулярним виразам. За допомогою метасимволів ви можете зробити набагато більше, ніж пошук одного символу. Ви можете шукати комбінації символів, використовувати їх динамічну кількість і вибирати діапазони. Всі спецсимволи можна розділити на два типи, це символи заміни, які замінюють собою звичайні символи, або оператори, які вказують скільки разів може повторюватися символ. Синтаксис регулярного виразу виглядатиме таким чином:

звичайний_символ спецсимвол_оператор

спецсимвол_заміни спецсимвол_оператор

  • \ - зі зворотної косою риси починаються буквені спецсимволи, а також він використовується якщо потрібно використовувати спецсимвол у вигляді будь-якого розділового знака;
  • ^ - Вказує на початок рядка;
  • $ - Вказує на кінець рядка;
  • * - Вказує, що попередній символ може повторюватися 0 або більше разів;
  • + - вказує, що попередній символ повинен повторитися більше одного або більше разів;
  • ? - Попередній символ може зустрічатися нуль або один раз;
  • (n)- Вказує скільки разів (n) потрібно повторити попередній символ;
  • (N,n)- Попередній символ може повторюватися від N до n разів;
  • . - будь-який символ, окрім перекладу рядка;
  • - будь-який символ, вказаний у дужках;
  • х|у- Символ x або символ y;
  • [^az]- будь-який символ, крім тих, що вказані у дужках;
  • - будь-який символ із зазначеного діапазону;
  • [^a-z]- будь-який символ, якого немає у діапазоні;
  • \b- позначає межу слова з пропуском;
  • \B- означає, що символ повинен бути всередині слова, наприклад, ux збігається з uxb або tuxedo, але не збігається з Linux;
  • \d- означає, що символ – цифра;
  • \D- нецифровий символ;
  • \n- Символ перекладу рядка;
  • \s- один із символів пробілу, пробіл, табуляція тощо;
  • \S- будь-який символ крім пробілу;
  • \t- Символ табуляції;
  • \v- Символ вертикальної табуляції;
  • \w- будь-який літерний символ, включаючи підкреслення;
  • \W- будь-який літерний символ, крім підкреслення;
  • \uXXX- Unicdoe символ.

Важливо, що перед літерними спецсимволами потрібно використовувати косу межу, щоб вказати, що далі йде спецсимвол. Правильно і зворотне, якщо ви хочете використовувати спецсимвол, який застосовується без косої межі як звичайний символ, то вам доведеться додати косу межу.

Наприклад, ви хочете знайти у тексті рядок 1+2=3. Якщо ви використовуєте цей рядок як регулярний вираз, то нічого не знайдете, тому що система інтерпретує плюс як спецсимвол, який повідомляє, що попередня одиниця повинна повторитися один або більше разів. Тому його потрібно екранувати: 1 \+ 2 = 3. Без екранування наш регулярний вираз відповідав би лише рядку 11=3 або 111=3 і так далі. Перед одною рису ставити не потрібно, тому що це не спецсимвол.

Приклади використання регулярних виразів

Тепер, коли ми розглянули основи і ви знаєте, як все працює, залишилося закріпити отримані знання про регулярні вирази linux grep на практиці. Два дуже корисні спецсимволи – це ^ і $, які позначають початок та кінець рядка. Наприклад, ми хочемо отримати всіх користувачів, зареєстрованих у нашій системі, ім'я яких починається на s. Тоді можна застосувати регулярний вираз "^s". Ви можете використовувати команду egrep:

egrep "^s" /etc/passwd

Якщо ми хочемо відбирати рядки за останнім символом у рядку, то для цього можна використовувати $. Наприклад, виберемо всіх системних користувачів, без оболонки, записи про таких користувачів закінчуються на false:

egrep "false$" /etc/passwd

Щоб вивести імена користувачів, які починаються на s або d, використовуйте такий вираз:

egrep "^" /etc/passwd

Такий самий результат можна отримати, використовуючи символ "|". Перший варіант більш придатний для діапазонів, а другий частіше застосовується для звичайних або/або:

egrep "^" /etc/passwd

Тепер давайте виберемо всіх користувачів, довжина імені яких становить не три символи. Ім'я користувача завершується двокрапкою. Ми можемо сказати, що воно може містити будь-який літерний символ, який має бути повторений три рази, перед двокрапкою:

egrep "^\w(3):" /etc/passwd

Висновки

У цій статті ми розглянули регулярні вирази Linux, але це були лише основи. Якщо копнути трохи глибше, ви знайдете, що за допомогою цього інструменту можна робити набагато більше цікавих речей. Час, витрачений на освоєння регулярних виразів, однозначно буде вартий того.

На завершення лекція від Яндекса про регулярні вирази:

Оригінал: Linux Fundamentals
Автор: Paul Cobbaut
Дата публікації: 16 жовтня 2014 р.
Переклад: А.Панін
Дата перекладу: 17 грудня 2014 р.

Розділ 19. Регулярні вирази

Механізм регулярних виразів є дуже потужним інструментом Linux. Регулярні вирази можуть використовуватися при роботі з безліччю програм, таких як bash, vi, rename, grep, sed та інших.

У цьому розділі представлені базові відомості про регулярні висловлювання.

Версії синтаксисів регулярних виразів

Існують три різні версії синтаксисів регулярних виразів: BRE: Basic Regular Expressions (Базовий синтаксис регулярних виразів) ERE: Extended Regular Expressions (Розширений синтаксис регулярних виразів) PCRE: Perl Regular Expressions (Синтаксис регулярних виразів мови програмування Perl)

Залежно від інструменту, що використовується, може використовуватися один або кілька згаданих синтаксисів.

Наприклад, інструмент grep підтримує параметр -E , що дозволяє примусово використовувати розширений синтаксис регулярних виразів (ERE) при розборі регулярного виразу, тоді як параметр -G дозволяє примусово використовувати базовий синтаксис регулярних виразів (BRE), а параметр -P - синтаксис регулярних виразів мови програмування Perl (PCRE)

Врахуйте і те, що інструмент grep також підтримує параметр -F, що дозволяє прочитати регулярне вираження без обробки.

Інструмент sed також підтримує параметри, які дають змогу вибирати синтаксис регулярних виразів.

Завжди читайте сторінки посібників використовуваних інструментів!

Утиліта grep

Виведення рядків, що збігаються із шаблоном

Утиліта grep є популярним інструментом Linux, призначеним для пошуку рядків, які збігаються з певним шаблоном. Нижче наведено приклади найпростіших регулярних виразів, які можна використовувати під час роботи з ним.

Це вміст використовуваного у прикладах тестового файлу. Цей файл містить три рядки (або три символи нового рядка). paul@rhel65:~$ cat names Tania Laura Valentina

При пошуку окремого символу будуть виводитись лише ті рядки, які містять заданий символ. paul@rhel65:~$ grep u names Laura paul@rhel65:~$ grep e names Valentina paul@rhel65:~$ grep i names Tania Valentina

Порівняння з шаблоном, використаним у цьому прикладі, здійснюється очевидним чином; у разі, якщо заданий символ зустрічається у рядку, утиліта grep виведе цей рядок.

Об'єднання символів

Для пошуку поєднань символів у рядках символи регулярного виразу повинні об'єднуватись аналогічним чином.

У цьому прикладі демонструється принцип роботи утиліти grep, відповідно до якого регулярному виразу ia буде відповідати рядок Tan ia , але не рядок V a lent i na, а регулярному виразу in - рядок Valent in a, але не рядок Ta ni a. paul@rhel65:~$ grep names Tania Laura Valentina paul@rhel65:~$ grep ia names Tania paul@rhel65:~$ grep in names Valentina paul@rhel65:~$

Один чи інший символ

Як у синтаксисі PCRE, і у синтаксисі ERE може використовуватися символ створення програмного каналу, який у разі буде представляти логічну операцію "АБО". У даному прикладі ми шукатимемо за допомогою утиліти grep рядки, в яких зустрічається символ i або символ a. paul@debian7:~$ cat list Tania Laura paul@debian7:~$ grep -E "i|a" list Tania Laura

Зверніть увагу, що ми використовуємо параметр -E утиліти grep для примусової інтерпретації нашого регулярного виразу як виразу, що використовує розширений синтаксис регулярних виразів (ERE).

Нам доведеться екранувати символ створення програмного каналу в регулярному виразі, що використовує базовий синтаксис регулярних виразів (BRE) для аналогічної інтерпретації цього символу як логічна операція "АБО". paul@debian7:~$ grep -G "i|a" list paul@debian7:~$ grep -G "i|a" list Tania Laura

Один чи більше збігів

Символ * відповідає нулю, одній або більшій кількості входжень попереднього символу, а символ + наступного символу. paul@debian7:~$ cat list2 ll lol lool loool paul@debian7:~$ grep -E "o*" list2 ll lol lool loool paul@debian7:~$ grep -E "o+" list2 lol lool loool paul@debian7: ~$

Збіг наприкінці рядка

У таких прикладах ми будемо використовувати цей файл: paul@debian7:~$ cat names Tania Laura Valentina Fleur Floor

У двох прикладах нижче показано методику використання символу долара для пошуку збігу в кінці рядка. paul@debian7:~$ grep a$ names Tania Laura Valentina paul@debian7:~$ grep r$ names Fleur Floor

Збіг на початку рядка

Символ вставки (^) дозволяє шукати збіги на початку (або з перших символів) рядка.

У прикладах використовується розглянутий вище файл. paul@debian7:~$ grep ^Val names Valentina paul@debian7:~$ grep ^F names Fleur Floor

Символи долара та вставки, що використовуються в регулярних виразах, називаються якорями (anchors).

Поділ слів

Екранування слів, що розшукуються, за допомогою символів пробілів не є вдалим рішенням (бо інші символи також можуть використовуватися як роздільники слів). У прикладі нижче показано методику використання послідовності символів для пошуку рядків із заданим словом, а не послідовністю символів: paul@debian7:~$ grep "\bover\b" text The winter is over. Can you get over there? paul@debian7:~$

Зверніть увагу на те, що утиліта grep також підтримує параметр -w, призначений для пошуку за словами. paul@debian7:~$ cat text The governer is governing. The winter is over. Can you get over there? paul@debian7:~$ grep -w над текстом Winter is over. Can you get over there? paul@debian7:~$

Параметри утиліти grep

Іноді виявляється простіше скомбінувати простий регулярний вираз з параметрами утиліти grep, ніж створити складніший регулярний вираз. Ці параметри обговорювалися раніше: grep -i grep -v grep -w grep -A5 grep -B5 grep -C5

Запобігання розкриттю регулярного вираження командною оболонкою

Символ долара є спеціальним символом як для регулярного вираження, так і для командної оболонки (згадайте про змінні командної оболонки та вбудовувані командні оболонки). Виходячи з цього, рекомендується за будь-яких обставин екранувати регулярні вирази, оскільки екранування регулярного виразу дозволяє запобігти розкриттю цього виразу командною оболонкою. paul@debian7:~$ grep "r$" names Fleur Floor rename

Утиліта rename

Реалізації утиліти rename

У дистрибутиві Debain Linux шляхом /usr/bin/rename розташоване посилання на сценарій /usr/bin/prename , що встановлюється з пакета perl . paul@pi ~ $ dpkg -S $(readlink -f $(which rename)) perl: /usr/bin/prename

У дистрибутивах, заснованих на дистрибутиві Red Hat, не створюється аналогічного символьного посилання для вказівки на описаний сценарій (звичайно ж, за винятком тих випадків, коли створюється символьне посилання на сценарій, встановлений вручну), тому в даному розділі не описуватиметься реалізація утиліти rename з дистрибутив Red Hat.

У дискусіях про утиліту rename в мережі Інтернет зазвичай відбувається плутанина через те, що рішення, які чудово працюють у дистрибутиві Debian (а також Ubuntu, xubuntu, Mint, ...), не можуть використовуватись у дистрибутиві Red Hat (а також CentOS , Fedora, ...).

Пакет perl

Команда rename насправді реалізована у формі сценарію, що використовує регулярні вирази мови програмування perl. З повним посібником з використання цього сценарію можна ознайомитись після введення команди perldoc perlrequick (після встановлення пакета perldoc). root@pi:~# aptitude install perl-doc Наступні НОВІ пакети будуть встановлені: perl-doc 0 пакетів оновлено, 1 встановлено нових, 0 пакетів позначено для видалення та 0 пакетів не оновлено. Необхідно одержати 8,170 kB архівів. Після розпакування 13.2 MB буде зайнято. Отримати: 1 http://mirrordirector.raspbian.org/raspbian/ wheezy/main perl-do... Отримано 8,170 kБ на 19с (412 kБ/с) Вибір раніше не вибраного пакета perl-doc. (Читання бази даних... на даний момент встановлено 67121 файл і каталог.) Розпаковується perl-doc (з.../perl-doc_5.14.2-21+rpi2_all.deb) ... /perldoc to /usr/bin/perldoc.stub by perl-doc" Тригери обробляються для man-db ... Налаштовується пакет perl-doc (5.14.2-21+rpi2) ... root@pi:~# perldoc perlrequick

Добре відомий синтаксис

Найчастіше утиліта rename використовується для пошуку файлів з іменами, що відповідають певному шаблону у формі рядка, та заміни даного рядка на інший рядок.

Зазвичай ця дія описується за допомогою регулярного виразу s/рядок/інший рядок/ , як показано в прикладі: paul@pi ~ $ ls abc allfiles.TXT bllfiles.TXT Scratch tennis2.TXT abc.conf backup cllfiles.TXT temp.TXT tennis. TXT paul@pi ~ $ rename "s/TXT/text/" * paul@pi ~ $ ls abc allfiles.text bllfiles.text Scratch tennis2.text abc.conf backup

А нижче наведено інший приклад, у якому використовується добре відомий синтаксис утиліти rename для повторної зміни розширень тих самих файлів: paul@pi ~ $ ls abc allfiles.text bllfiles.text .text paul@pi ~ $ rename "s/text/txt/" *.text paul@pi ~ $ ls abc allfiles.txt bllfiles.txt Scratch tennis2.txt abc.conf backup cllfiles.txt temp.txt tennis.txt paul @pi ~ $

Ці два приклади є працездатними з тієї причини, що рядки, які ми використовуємо, зустрічаються виключно в розширеннях файлів. Не забувайте про те, що розширення файлів не мають значення під час роботи з командною оболонкою bash.

У наступному прикладі продемонстровано проблему, з якою можна зіткнутися під час використання даного синтаксису. paul@pi ~ $ touch atxt.txt paul@pi ~ $ rename "s/txt/problem/" atxt.txt paul@pi ~ $ ls abc allfiles.txt backup cllfiles.txt temp.txt tennis.txt abc.conf aproblem .txt bllfiles.txt Scratch tennis2.txt paul@pi ~ $

При виконанні аналізованої команди здійснюється заміна виключно першого входження рядка, що розшукується.

Глобальна заміна

Синтаксис, використаний у попередньому прикладі, може бути описаний наступним чином: s/регулярний вираз/рядок для заміни/ . Цей опис є простим і очевидним, так як вам доведеться лише розмістити регулярне вираження між двома першими слешами і рядок для заміни між двома останніми слешами.

У наступному прикладі цей синтаксис трохи розширюється завдяки додаванню модифікатора. paul@pi ~ $ rename -n "s/TXT/txt/g" aTXT.TXT aTXT.TXT renamed as atxt.txt paul@pi ~ $

Тепер використовуваний нами синтаксис може бути описаний як s/регулярне вираз/рядок для заміни/g де модифікатор s позначає операцію заміни (switch), а модифікатор g - повідомляє про необхідність здійснення глобальної заміни (global).

Зверніть увагу на те, що в даному прикладі був використаний параметр -n для виведення інформації про операцію, що виконується (замість виконання самої операції, що полягає в безпосередньому перейменуванні файлу).

Заміна без урахування регістру

Іншим модифікатором, який може бути корисним, є модифікатор i . У прикладі нижче показано методику заміни рядка на інший рядок без урахування регістру. paul@debian7:~/files$ ls file1.text file2.TEXT file3.txt paul@debian7:~/files$ rename "s/.text/.txt/i" * paul@debian7:~/files$ ls file1. txt file2.txt file3.txt paul@debian7:~/files$

Зміна розширень

Інтерфейс командного рядка Linux не має уявлення про розширення файлів, аналогічних застосовуваним в операційній системі MS-DOS, але багато користувачів та додатки з графічним інтерфейсом використовують їх.

У цьому розділі наведено приклад використання утиліти rename для зміни виключно розширень файлів. У прикладі використовується символ долара для вказівки на те, що точкою відліку заміни є закінчення імені файлу. paul@pi ~ $ ls *.txt allfiles.txt bllfiles.txt cllfiles.txt really.txt.txt temp.txt tennis.txt paul@pi ~ $ rename "s/.txt$/.TXT/" *.txt paul @pi ~ $ ls *.TXT allfiles.TXT bllfiles.TXT cllfiles.TXT really.txt.TXT temp.TXT tennis.TXT paul@pi ~ $

Зверніть увагу на те, що символ долара в рамках регулярного виразу означає закінчення рядка. Без символу долара виконання цієї команди має завершитись невдачею в момент обробки імені файлу really.txt.txt.

Утиліта sed

Редактор потоку даних

Редактор потоку даних (stream editor) або, для стислості, утиліта sed використовує регулярні вирази для модифікації потоку даних.

У цьому прикладі утиліта sed використовується для заміни рядка. echo понеділок | sed "s/Понеділок/Втор// Вівторок

Слеши можуть бути замінені на деякі інші символи, які можуть виявитися зручнішими та підвищити читаність команди в ряді випадків. echo Понеділок | sed "s:Понеділок:Втор:" Вівторок echo Понеділок | sed "s_Понеділок_Вторник_" Вівторок echo Понеділок | sed "s | Понеділок | Втор |" Вівторок

Інтерактивний редактор

Незважаючи на те, що утиліта sed призначена для обробки потоків даних, вона також може використовуватись для інтерактивної обробки файлів. paul@debian7:~/files$ echo Понеділок > today paul@debian7:~/files$ cat today Понеділок paul@debian7:~/files$ sed -i "s/Понеділок/Втор/" today paul@debian7:~/files $ cat today Вівторок

Символ амперсанда може використовуватися для посилання на шуканий (і знайдений) рядок.

У цьому прикладі амперсанд використовується для подвоєння знайдених рядків. echo понеділок | sed "s/Понеділок/&&/" ПонеділокПонеділок echo Понеділок | sed "s/нік/&&/" Понеділок

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

Розгляньте наступний приклад: paul@debian7:~$ echo Sunday | sed "s_\(Sun\)_\1ny_" Sunnyday paul@debian7:~$ echo Sunday | sed "s_\(Sun\)_\1ny \1_" Sunny Sunday

Крапка для позначення будь-якого символу

У регулярному виразі простий символ точки може позначати будь-який символ. paul@debian7:~$ echo 2014-04-01 | sed "s/....-..-../YYYY-MM-DD/" YYYY-MM-DD paul@debian7:~$ echo abcd-ef-gh | sed "s/....-..-../YYYY-MM-DD/" YYYY-MM-DD

У разі використання більш ніж однієї пари круглих дужок посилання на кожну з них може бути здійснено шляхом використання послідовних числових значень. paul@debian7:~$ echo 2014-04-01 | sed "s/\(....\)-\(..\)-\(..\)/\1+\2+\3/" 2014+04+01 paul@debian7:~$ echo 2014 -04-01 | sed "s/\(....\)-\(..\)-\(..\)/\3:\2:\1/" 01:04:2014

Ця можливість називається угрупуванням (grouping).

Пробіл

Послідовність символів \s може використовуватися для посилання на символ, як символ пробілу або табуляції.

У цьому прикладі здійснюється глобальний пошук послідовностей символів пробілів (s), які замінюються на 1 символ пробілу. paul@debian7:~$ echo -e "сьогодні\tтеплий\tдень" сьогодні теплий день paul@debian7:~$ echo -e "сьогодні\tтеплий\tдень" | sed "s_\s_ _g" сьогодні теплий день

Необов'язкові входження

Символ питання знаку вказує на те, що попередній символ є необов'язковим.

У прикладі нижче здійснюється пошук послідовності із трьох символів o, причому третій символ o є необов'язковим. paul@debian7:~$ cat list2 ll lol lool loool paul@debian7:~$ grep -E "ooo?" list2 lool loool paul@debian7:~$ cat list2 | sed "s/ooo\?/A/" ll lol lAl lAl

Рівно n повторень

Ви можете вказати точну кількість повторень попереднього символу.

У цьому прикладі здійснюється пошук рядків з трьома символами o. paul@debian7:~$ cat list2 ll lol lool loool paul@debian7:~$ grep -E "o(3)" list2 loool paul@debian7:~$ cat list2 | sed "s/o\(3\)/A/" ll lol lool lAl paul@debian7:~$

Від n до m повторень

А в даному прикладі ми чітко вказуємо, що символ має повторюватися від мінімальної (2) до максимальної (3) кількості разів. paul@debian7:~$ cat list2 ll lol lool loool paul@debian7:~$ grep -E "o(2,3)" list2 lool loool paul@debian7:~$ grep "o\(2,3\)" list2 lool loool paul@debian7:~$ cat list2 | sed "s/o\(2,3\)/A/" ll lol lAl lAl paul@debian7:~$

Історія командної оболонки bash

Командна оболонка bash також може інтерпретувати деякі регулярні вирази.

У цьому прикладі показана методика маніпуляцій із символом знака оклику в рамках маски пошуку в історії командної оболонки bash. paul@debian7:~$ mkdir hist paul@debian7:~$ cd hist/ paul@debian7:~/hist$ touch file1 file2 file3 paul@debian7:~/hist$ ls -l file1 -rw-r--r-- 1 paul paul 0 квіт 15 22:07 file1 paul@debian7:~/hist$ !l ls -l file1 -rw-r--r-- 1 paul paul 0 квіт 15 22:07 file1 paul@debian7:~/hist $ !l:s/1/3 ls -l file3 -rw-r--r-- 1 paul paul 0 Кві 15 22:07 file3 paul@debian7:~/hist$

Ця методика також працює у разі використання чисел під час читання історії команд командної оболонки bash. paul@debian7:~/hist$ history 6 2089 mkdir hist 2090 cd hist/ 2091 touch file1 file2 file3 2092 ls -l file1 2093 ls -l file3 2094 history 6 paul@debian7:~/ rw-r--r-- 1 paul paul 0 квіт 15 22:07 file1 paul@debian7:~/hist$ !2092:s/1/2 ls -l file2 -rw-r--r-- 1 paul paul 0 кві 15 22:07 file2 paul@debian7:~/hist$