Привіт усім!
В даній статті розглядаються правила розпізнавання шаблонів командним інтерпретатором Bash (Bourne Again SHell).
Шаблони
Будь-який символ, який присутній у шаблоні, відмінний від спеціальних символів описаних нижче, означають себе. Бек-слеш (“\”) забирає спеціальне значення наступного символу і сам символ зворотнього-слешу (“\”) не враховується при співставлені шаблону. Спеціальні символи шаблону повинні міститись після зворотнього-слешу, якщо вони повинні співставлятись літерально (без спеціального значення).
Спеціальні символи шаблонів мають наступні значення:
- * - позначає будь-який рядок, включаючи нульової довжини;
- ? - позначає будь-який один символ;
- [...] - позначає будь-який з символів, які перелічені в квадратних дужках. Пара символів, які розділені знаком тире (“-” або мінус) позначає проміжок, який міститься між символами — будь-який символ, який попадає між даними двома символами включно, використовуючи поточну локаль і набір символів, буде відображати дану частину шаблону. Якщо перший символ, який міститься після символу відкриття квадратних дужок (“[”), являється “!” або “^”, в такому разі шаблон буде співпадати з символами, які не містяться в наборі символів, вказаних в даних квадратних дужках. Символ “-” може міститись в шаблоні (не позначаючи проміжок), якщо він стоїть першим або останнім в списку. В списку може міститись символ “]”, який не відображає спеціального значення, якщо він стоїть першим в списку. Порядок сортування символів у проміжку символів визначається поточними налаштуваннями локалі і значеннями змінних командного рядка LC_COLLATE i CL_ALL, якщо дані встановлені. Наприклад, якщо поточна локаль — “С”, шаблон “[a-dx-z]” являється еквівалентним “[abcdxyz]”. Багато локалей сортують символи в словниковому порядку, і у них шаблон “[a-dx-z]” не являється еквівалентним “[abcdxyz]”; натомість, він може бути еквівалентним, наприклад, [aBbCcDdxXyYz]. Для того, щоб примусити командний інтерпретатор використовувати традиційний проміжки символів у виразах квадратних дужок, слід встановити використання “С”-локалі, встановлюючи значення змінних середовища LC_COLLATE або LC_ALL у значення “С”, або увімкнути опцію командного інтерпретатора globasciiranges. Всередині виразу квадратних дужок, можна вказати класи символів використовуючи синтаксис “[[:клас:]]”, де “клас” являє собою один з наступних класів, визначених у стандарті POSIX:
- “alnum” — означає усі букви в верхньому і нижньому регістрах, включаючи цифри від 0 до 9;
- “alpha” — усі букви в верхньому і нижньому регістрах (“A-Za-z”);
- “ascii” — символи ASCII;
- “blank” — символ пробілу і табуляції (“ \t”);
- “cntrl” — контрольні символи;
- “digit” — усі цифри від (0-9);
- “graph” — візуальні символи (усе крім пробілів і контрольних символів);
- “lower” — усі літери нижнього регістру (a-z);
- “print” — візуальні символи і символи пробілів;
- “punct” — символи пунктуації (,.:\][; і інше);
- “space” — усі символи пробілів включаючи символи переходу на новий рядок;
- “upper” — усі літери верхнього регістру (A-Z);
- “word” — символи слів (усі цифри і букви разом з символом підкреслення);
- “xdigit” — символи, які відображають шістнадцяткові цифри (0-9A-Fa-f).
Клас символу співпадає з будь-яким символом даного класу. Всередині шаблону альтернативи (себто квадратних дужок) може міститись клас еквівалентності, який визначається синтаксисом "[=c=]". Він співпадає з усіма символами, які мають те саме значення (як визначено в поточній локалі) що і вказаний символ “с”.
За допомогою синтаксису “[.символ.]” можна розпізнавати символи по POSIX-назві символу “символ”. Наприклад, шаблон “[[.backslash.]]“ буде розпізнавати символ “\”. До них також відносять:
Ім'я символу | Символ | Клас символу |
NUL | | cntrl |
SOH | | cntrl |
STX | | cntrl |
ETX | | cntrl |
EOT | | cntrl |
ENQ | | cntrl |
ACK | | cntrl |
alert | | cntrl |
backspace | | cntrl |
tab | | cntrl, space, blank |
newline | | cntrl, space |
vertical-tab | | cntrl, space |
form-feed | | cntrl, space |
carriage-return | | cntrl, space |
SO | | cntrl |
SI | | cntrl |
DLE | | cntrl |
DC1 | | cntrl |
DC2 | | cntrl |
DC3 | | cntrl |
DC4 | | cntrl |
NAK | | cntrl |
SYN | | cntrl |
ETB | | cntrl |
CAN | | cntrl |
EM | | cntrl |
SUB | | cntrl |
ESC | | cntrl |
IS4 | | cntrl |
IS3 | | cntrl |
IS2 | | cntrl |
IS1 | | cntrl |
space | | space, print, blank |
exclamation-mark | ! | punct, print, graph |
quotation-mark | “ | punct, print, graph |
number-sign | # | punct, print, graph |
dollar-sign | $ | punct, print, graph |
percent-sign | % | punct, print, graph |
ampersand | & | punct, print, graph |
apostrophe | ' | punct, print, graph |
left-parenthesis | ( | punct, print, graph |
right-parenthesis | ) | punct, print, graph |
asterisk | * | punct, print, graph |
plus-sign | + | punct, print, graph |
comma | , | punct, print, graph |
hyphen | - | punct, print, graph |
period | . | punct, print, graph |
slash | / | punct, print, graph |
zero | 0 | digit, xdigit, print, graph |
one | 1 | digit, xdigit, print, graph |
two | 2 | digit, xdigit, print, graph |
three | 3 | digit, xdigit, print, graph |
four | 4 | digit, xdigit, print, graph |
five | 5 | digit, xdigit, print, graph |
six | 6 | digit, xdigit, print, graph |
seven | 7 | digit, xdigit, print, graph |
eight | 8 | digit, xdigit, print, graph |
nine | 9 | digit, xdigit, print, graph |
colon | : | punct, print, graph |
semicolon | ; | punct, print, graph |
less-than-sign | < | punct, print, graph |
equals-sign | | punct, print, graph |
greater-than-sign | > | punct, print, graph |
question-mark | ? | punct, print, graph |
commercial-at | @ | punct, print, graph |
left-square-bracket | [ | punct, print, graph |
backslash | \ | punct, print, graph |
right-square-bracket | ] | punct, print, graph |
circumflex | ^ | punct, print, graph |
underscore | _ | punct, print, graph |
grave-accent | ` | punct, print, graph |
left-curly-bracket | { | punct, print, graph |
vertical-line | | | punct, print, graph |
right-curly-bracket | } | punct, print, graph |
tilde | ~ | punct, print, graph |
DEL | | cntrl |
Якщо увімкнена опція командного рядка extglob, Bash буде розпізнавати шаблони з розширеними можливостями, які вказані у наступному списку (даний режим шаблонів також включається за використанням оператора “=~”). Термін “список-шаблонів” являють собою один або більше шаблонів, розділених символом “|”. Складні шаблони можуть бути сформованими, використовуючи наступні під-шаблони:
- ?(список-шаблонів) — відображає нуль або один випадок вказаних шаблонів;
- *(список-шаблонів) — відображає нуль або множину випадків вказаного шаблону;
- @(список-шаблонів) — відображає один випадок з вказаних шаблонів;
- +(список-шаблонів) — відображає один або більше випадків вказаних шаблонів;
- !(список-шаблонів) — відображає будь-що, окрім вказаних шаблонів;
Приклади
Розглянемо наступний простий приклад порівняння довільних рядків з шаблонами:
#!/bin/bash
# створюємо змінну для використання з шаблоном
str="this script is from kytok.org.ua"
pattern='[[:alpha:]]*kytok.org.ua'
# використовуємо шаблон з класом до рядка символів
if [[ $str = $pattern ]]
then
echo "рядок '$str' співпадає з шаблоном '$pattern'"
else
echo "рядок '$str' не співпадає з шаблоном '$pattern'"
fi
# змінюємо значення змінної str
str="1 script is from kytok.org.ua"
pattern='[[.one.]]*'
# використовуємо POSIX-ім'я символу в шаблоні
if [[ $str = $pattern ]]
then
echo "рядок '$str' співпадає з шаблоном '$pattern'"
else
echo "рядок '$str' не співпадає з шаблоном '$pattern'"
fi
# неподібний шаблон
if [[ $str = *[[.two.]]* ]]
then
echo "рядок '$str' співпадає з шаблоном '*[[.two.]]*'"
else
echo "рядок '$str' не співпадає з шаблоном '*[[.two.]]*'"
fi
Після виконання вказаного скрипта, ми отримаємо наступний вивід на екран (скрипт знаходиться у файлі pattern_test.sh):
[caption id="attachment_866" align="aligncenter" width="1268"]
Вивід простого скрипта, який показує використання шаблонів у командному інтерпретаторі Bash[/caption]
Розглянемо приклад з використанням оператора розширених шаблонів:
#!/bin/bash
# перевіряємо, чи подібний переданий параметр
# до IPv4 інтернет-адреси
if [[ "$1" =~ ^((([[:digit:]]{1,3})\.){3}[[:digit:]]{1,3})$ ]]
then
echo "Рядок $1 подібний до IPv4 адреси"
else
echo "Рядок $1 не подібний до IPv4 адреси"
fi
Даний скрипт перевіряє перший переданий параметр скрипта на подібність до IPv4-адреси, але він не перевіряє її валідність — тобто можливість її застосування до реальної машини в мережі. Символ “^” - означає початок символьного рядка, а символ “$” - його кінець. Всередині шаблону використано клас символів “digit” для розпізнавання усіх цифр від 0-9. Конструкція “{1,3}” означає співпадання попереднього шаблону від одного до трьох разів включно (в нашому випадку це повинні бути цифри). Конструкція “{3}” вказує на необхідну кількість співпадань шаблону, який стоїть перед нею. Тобто конструкція “([[:digit:]]{1,3}\.)” (від однієї до трьох цифр після яких йде символ крапки) повинна повторюватися три рази в рядку символів (якщо після неї стоїть конструкція “{3}”). Після трьох повторень цифр з крапками в кінці, повинно розміщуватись від однієї до трьох цифр без будь-яких символів за ними, на що вказує частина шаблону “[[:digit:]]{1,3})$”. Виконання даного скрипта може вивести наступний результат в командний рядок (файл скрипта називається “ext_pattern_test.sh”):
[caption id="attachment_867" align="aligncenter" width="946"]
Вивід простого скрипта, який показує використання шаблонів інтерпретатора Bash для розпізнавання IPv4 інтернет адреси[/caption]