glob(7) шаблоны полных имён файлов

ОПИСАНИЕ

Давным-давно, во времена UNIX V6, существовала программа /etc/glob, которая могла раскрывать шаблоны подстановки. Очень скоро она стала встроенной функцией командной оболочки.

В наши дни существует библиотечная функция glob(3), которая выполняет эту задачу для пользовательских программ.

Следующие правила приведены в соответствии со стандартом POSIX.2, 3.13.

Тип шаблона

Строка считается шаблоном подстановки, если содержит в себе один из символов '?', '*' или '['. Globbing — это операция, которая раскрывает шаблон подстановки в список имён путей, соответствующих данному шаблону. Соответствие определяется следующими правилами:

'?' (без учета кавычек) соответствует любому одному символу.

'*' (без учета кавычек) соответствует любой строке, включая пустую строку.

Классы символов

Выражение «[...]», где первый символ после открывающей '[' - не равен '!', соответствует одному символу, который может быть любым символом из набора, находящегося внутри скобок. Строка внутри скобок не может быть пустой, таким образом, ']' также может находиться внутри скобок и выступать в качестве первого символа (то есть «[][!]» будет соответствовать трем символам '[', ']' и '!').

Диапазоны

Два символа, разделённые '-', образуют особое выражение — диапазон (то есть «[A-Fa-f0-9]» будет эквивалентен записи «[ABCDEFabcdef0123456789]»). Сюда также может входить и сам '-' в качестве начального или конечного символа (то есть «[]-]» будет соответствовать только двум символам - ']' и '-', а «[--0]» — трем символам: '-', '.', '0', так как '/' не может быть использован).

Разность множеств

Выражение «[!...]» соответствует одному любому символу, который не входит в множество, получаемое путем удаления первого '!' (то есть «[!]a-]» будет соответствовать любому одному символу за исключением ']', 'a' и '-').

Специальное значение '?', '*' и '[' может быть аннулировано путём экранирования их обратной косой чертой или, в случае, когда они являются частью оболочки командной строки, путём заключения их в кавычки. Внутри квадратных скобок эти символы не имеют специального значения. Таким образом, «[[?*\]» совпадает с четырьмя символами '[', '?', '*' и '\'.

Полные составные пути

Раскрытие (globbing) применяется к каждой части полного составного имени файла отдельно. Символ '/' в полном имени файла не может совпадать с шаблоном '?' или '*', а только с диапазоном подобным «[.-0]». Диапазон не может включать в себя символ '/', поскольку это будет считаться синтаксической ошибкой.

Если имя файла начинается с '.', то этот символ должен быть обязательно указан в шаблоне (таким образом, rm * не удалит .profile, а tar c * заархивирует не все файлы; лучше использовать tar c .).

Пустые списки

Выше было приведено простое и замечательное правило из оригинального определения UNIX: «раскрытие шаблона — это операция, преобразующая шаблон в список соответствующих ему полных имён файлов». Оно допускает существование шаблона, соответствующего пустому списку, например:

    xv -wait 0 *.gif *.jpg

где, возможно, файлы *.gif на самом деле отсутствуют (и это не ошибка). Несмотря на это, в POSIX требуется, чтобы шаблон, синтаксически неправильный или раскрывающийся в пустой список путей к файлам, оставался без изменений. В bash можно принудительно включить классическое поведение с помощью команды:


    shopt -s nullglob

Подобная проблема может проявиться вновь. Например, там, где в старых сценариях использовалось

    rm `find . -name "*~"`

в новых сценариях используется

    rm -f nosuchfile `find . -name "*~"`

для избежания сообщений об ошибках rm, вызванного с пустым списком аргументов.

ЗАМЕЧАНИЯ

Регулярные выражения

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

Теперь, когда в квадратных скобках у регулярных выражений для отрицания используется '^', в POSIX оговаривается, что эффект шаблона «[^...]» не определён.

Классы символов и интернационализация

Изначально диапазоны были определены для символов ASCII, так что «[ -%]» соответствует «[ !"#$%]», а «[a-z]» соответствует «любому символу нижнего регистра». В некоторых реализациях UNIX это обобщено так, что диапазон X-Y соответствует всем символам, коды которых находятся между X и Y. Однако, это требует знания способа кодирования символов в локальной системе и, более того, не удобно, если последовательность сортировки для локального алфавита отличается от последовательности кодов символов. Поэтому в POSIX значительно расширено обозначение квадратных скобок как для шаблонов файлов, так и для регулярных выражений. Выше встретилось три типа выражений в скобках: отрицание (i), указанный явно символ (ii) и диапазон (iii). В POSIX диапазоны определены в более удобном с точки зрения интернационализации виде, а также добавлены три новых типа:

(iii) Диапазоны X-Y включают в себя все символы, находящиеся между X и Y (включительно) в соответствии с текущей последовательностью сортировки, определённой в категории LC_COLLATE текущей локали.

(iv) Именованные классы символов, такие, как:

[:alnum:]  [:alpha:]  [:blank:]  [:cntrl:]
[:digit:]  [:graph:]  [:lower:]  [:print:]
[:punct:]  [:space:]  [:upper:]  [:xdigit:]
Благодаря им можно указать значение «[[:lower:]]» вместо «[a-z]», и это будет работать для Дании, где в алфавите есть три буквы, стоящие после «z». Эти классы символов определяются категорией LC_CTYPE текущей локали.

(v) Сортировочные символы, такие, как «[.ch.]» или «[.a-acute.]», строка которых, лежащая между «[.» и «.]», является элементом сортировки, определённым для текущей локали. Заметим, что это может быть многосимвольный элемент.

(vi) Классы эквивалентности, такие, как «[=a=]», где строка между «[=» и «=]» является любым элементом сортировки из своего класса эквивалентности, определённого в текущей локали. Например, «[[=a=]]» может быть эквивалентно «[aáàäâ]», то есть «[a[.a-acute.][.a-grave.][.a-umlaut.][.a-circumflex.]]».