Привіт усім! В даній статті розглядаються правила розпізнавання шаблонів командним інтерпретатором 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-markpunct, 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
    zero0digit, xdigit, print, graph
    one1digit, xdigit, print, graph
    two2digit, xdigit, print, graph
    three3digit, xdigit, print, graph
    four4digit, xdigit, print, graph
    five5digit, xdigit, print, graph
    six6digit, xdigit, print, graph
    seven7digit, xdigit, print, graph
    eight8digit, xdigit, print, graph
    nine9digit, 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 Вивід простого скрипта, який показує використання шаблонів у командному інтерпретаторі 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 інтернет адреси Вивід простого скрипта, який показує використання шаблонів інтерпретатора Bash для розпізнавання IPv4 інтернет адреси[/caption]