glob - шаблоны полных имен файлов
НАЗВАНИЕglob - шаблоны полных имен файлов
ОПИСАНИЕ
Раньше в Unix V6 существовала программа /etc/glob,
обрабатывающая шаблоны. Затем обработка шаблонов была
встроена в shell.
Сейчас существует библиотечная функция glob(3),
выполняющая эту обработку для программ пользователя.
Правила обработки приведены ниже (POSIX 1003.2, 3.13).
ШАБЛОНЫ
Строка считается шаблоном, если она содержит один из
символов "?", "*" или "[". Раскрытие (globbing) шаблона -
это операция, преобразующая шаблон в список
соответствующих ему полных имен файлов. Правила
соответствия определены следующим образом:
"?" (не в квадратных скобках) соответствует любому
одиночному символу.
"*" (не в квадратных скобках) соответствует любой строке,
включая пустую строку.
Классы символов
Выражение "[...]", в котором первый символ после ведущей
"[" не является "!", совпадает с любым одиночным символом,
входящим в строку, заключенную в квадратные скобки. Строка
в квадратных скобках не может быть пустой; поэтому "]"
может встречаться в скобках, если он стоит в первой
позиции. (Таким образом, "[][!]" совпадает с тремя
символами: "[", "]" и "!".)
Диапазоны
Существует одно специальное соглашение: два символа,
разделенные "-", означают диапазон. (Таким образом,
выражение "A-Fa-f0-9]" эквивалентно "[ABCDE-
Fabcdef0123456789]".) Указать "-" в его символьном
значении можно, поставив его первым или последним символом
между скобками. (То есть "[]-]" совпадает с двумя
символами: "]" и "-", а "[--/]" совпадает с тремя
символами: "-", "." и "/").
Исключение символов
Выражение "[!...]" совпадает с любым одиночным символом,
не входящим в строку, находящуюся между "[!" и "]". Таким
образом, "[!]a-]" совпадает с любым одиночным символом,
кроме "]", "a" и "-".
Специальное значение "?", "*" и "[" может быть
аннулировано путем экранирования их обратным слэшем (\)
или в случае, когда они являются частью командной строки
shell, путем заключения их в кавычки. Внутри квадратных
скобок эти символы не имеют специального значения. Таким
образом, "[[?*\]" совпадает с четырьмя символами: "[",
"?", "*" и "\".
ПУТИ К ФАЙЛУ
Раскрытие (globbing) применяется к каждой части путевого
имени файла отдельно. "/" в путевом имени файла не может
совпадать с "?" или "*", а только с диапазоном, таким, как
"[.-0]". Диапазон не может включать в себя символ "/",
поскольку это будет считаться синтаксической ошибкой.
Если путевое имя файла начинается с ".", то этот символ
должен быть обязательно указан в шаблоне. (Таким образом,
"rm *" не удалит .profile, а "tar c *" не заархивирует все
файлы; лучше использовать "tar c ." .)
ПУСТОЙ СПИСОК
Выше было приведено простое и замечательное правило:
"раскрытие шаблона - это операция, преобразующая шаблон в
список соответствующих ему полных имен файлов ", - это
оригинальное определение Unix. Оно допускает существование
шаблона, соответствующего пустому списку, например, как в
xv -wait 0 *.gif *.jpg ,
где, возможно, файлы *.gif на самом деле отсутствуют (и
это не ошибка). Hесмотря на это, POSIX требует, чтобы
шаблон, синтаксически неправильный или "раскрывающийся" в
пустой список путей к файлам, оставался без изменений. В
bash можно принудительно запустить классическое поведение,
установив allow_null_glob_expansion=true.
Подобная проблема может проявиться вновь. Hапример, там,
где старые скрипты использовали
rm `find . -name "*~"`
, новые скрипты (для избежания сообщений об ошибках rm,
вызванных с пустым списком аргументов) требуют
rm -f nosuchfile `find . -name "*~"`
ЗАМЕЧАНИЯ
Регулярные выражения
Обратите внимания, что обсуждаемые шаблоны не являются
регулярными выражениями, хотя они несколько похожи.
Во-первых, они используются для выявления совпадений с
именами файлов, а не с текстом. Во-вторых, используются
разные соглашения: например, в регулярном выражении "*"
означает ноль или более копий предшествующей этому символу
строки.
Теперь, когда в квадратных скобках регулярных выражений
для отрицания используется "^", POSIX оговаривает, что
эффект шаблона "[^...]" не определен.
Классы символов и интернационализация
Изначально диапазоны были определены для символов ASCII,
так что "[ -%]" соответствует "[ !"#$%]", а "[a-z]"
соответствует "любому символу нижнего регистра". Hекоторые
реализации 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=]", где
строка между "[=" и "=]" является любым элементом
сортировки из своего класса эквивалентности, определенного
в текущей локали. Hапример, "[[=е=]]" может быть
эквивалентно "[её]".