Перейти к основному содержанию
Рецепты Linux

Main navigation

  • Основы
  • Система
  • Команды
  • Программы
  • Дистро
  • Интерфейсы
  • Устройства
  • Доки
User account menu
  • Войти

Строка навигации

  1. Главная
  2. Linux: Введение
  3. Возможности командной оболочки

Генерация имён файлов

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

Шаблоны

Шаблон в командном интерпретаторе используется примерно в тех же целях, что и регулярное выражение, упомянутое в лекции Работа с текстовыми данными: для поиска строк определённй структуры среди множества разнообразных строк. В отличие от регулярного выражения, шаблон всегда примеряется к строке целиком, кроме того, он устроен значительно проще (а значит, и беднее).

Символы в шаблоне разделяются на обычные и специальные. Обычные символы соответствуют таким же символам в строке, а специальные обрабатываются особым образом:

  1. Шаблону, состоящему только из обычных символов, соответствует единственная строка, состоящая из тех же символов в том же порядке. Например, шаблону «abc» соответствует строка abc, но не aBc или ABC, потому что большие и маленькие буквы различаются.
  2. Шаблону, состоящему из единственного спецсимвола «*», соответствует любая строка любой длины (в том числе и пустая).
  3. Шаблону, состоящему из единственного спецсимвола «?», соответствует любая строка длиной в один символ, например, a, + или @, но не ab или 8888.
  4. Шаблону, состоящему из любых символов, заключённых в квадратные скобки «[» и «]» соответствует строка длиной в один символ, причём этот символ должен встречаться среди заключённых в скобки. Например, шаблону «[bar]» соответствуют только строки a, b и r, но не c, B, bar или ab. Символы внутри скобок можно не перечислять полностью, а задавать диапазон, в начале которого стоит символ с наименьшим ASCII-кодом, затем следует «-», а затем — символ с наибольшим ASCII-кодом. Например, шаблону «[0-9a-fA-F]» соответствует одна шестнадцатеричная цифра (скажем, 5, e или C). Если после «[» в шаблоне следует «!», то ему соответствует строка из одного символа не перечисленного между скобками.
  5. Шаблону, состоящему из нескольких частей, соответствует строка, которую можно разбить на столько же подстрок (возможно, пустых), причём первая подстрока будет отвечать первой части шаблона, вторая — второй части и т. д. Например, шаблону «a*b?c» будут соответствовать строки ab@c («*» соответствует пустая подстрока), a+b=c и aaabbc, но не соответствовать abc («?» соответствует подстрока c, а для «c» соответствия не находится), @ab@c (нет соответствия для «a») или aaabbbc (из трёх b первое соответствует «b», второе — «?», а вот третье приходится на «c»).
шаблон
Строка специального формата, используемая в процедурах текстового поиска. Говорят, что строка соответствует шаблону, если можно по определённым правилам каждому символу строки поставить в соответствие символ шаблона. В Linux наиболее популярны шаблоны в формате командного интерпретатора и регулярные выражения.

Использование шаблонов

Шаблоны используются в нескольких конструкциях shell. Главное место их применения — командная строка. Если оболочка видит в командной строке шаблон, она немедленно заменяет его на список файлов, имена которых ему соответстуют. Команда, которая затем вызывается, получает в качестве параметров список файлов уже безо всяких шаблонов, как если бы этот список пользователь ввёл вручную. Эта способность командного интерпретатора называется генерацией имён файлов.

[methody@localhost methody]$ ls .bash*
 .bash_history  .bash_logout  .bash_profile  .bashrc
[methody@localhost methody]$ /bin/e*
 /bin/ed /bin/egrep /bin/ex
[methody@localhost methody]$ ls *a*
 -filename-with-
[methody@localhost methody]$ ls -dF *[ao]*
 Documents/  examples/  loop  to.sort*

Пример 7. Использование шаблона в командной строке

Мефодий, как это случается с новичками, немедленно натолкнулся на несколько «подводных камней», неизбежных в ситуации, когда конечный результат неизвестен. Только первая команда сработала не вопреки его ожиданиям: шаблон «.bash*» был превращён командной оболочкой в список файлов, начинающихся на .bash, этот список получила в качестве параметров командной строки ls, после чего честно его вывела. С «/bin/e*» Мефодию повезло — этот шаблон превратился в список файлов из каталога /bin, начинающихся на «e», и первым файлом в списке оказалась безобидная утилита /bin/echo. Поскольку в командной строке ничего, кроме шаблона, не было, именно строка /bin/echo была воспринята оболочкой в качестве команды, которой — в качестве параметров — были переданы остальные элементы списка — /bin/ed, /bin/egrep и /bin/ex.

Можно вспомнить про нулевой параметр командной строки, обсуждавшийся в лекции Доступ процессов к файлам и каталогам.

Что же касается ls *a*, то, по расчётам Мефодия, эта команда должна была выдать список файлов в текущем каталоге, имя которых содержит «a». Вместо этого на экран вывелось имя файла из подкаталога examples... Впрочем, никакой чёрной магии тут нет. Во-первых, имена файлов вида «.bash*» хотя и содержат «a», но начинаются на точку, и, стало быть, считаются скрытыми. Скрытые файлы попадают в результат генерации имён только если точка в начале указана явно (как в первой команде примера). Поэтому по шаблону «*a*» в домашнем каталоге Мефодия bash нашёл только подкаталог с именем examples, его-то он и передал в качестве параметра утилите ls. Что вывелось на экран в результате образовавшейся команды ls examples? Конечно, содержимое каталога. Шаблон в последней команде из примера, «*[ao]*», был превращён в список файлов, чьи имена содержат «a» или «o» — Documents examples loop to.sort, а ключ «-d» потребовал у ls показывать информацию о каталогах, а не об их содержимом. В соответствии с ключом «-F», ls расставил «/» после каталогов и «*» после исполняемых файлов.

Ещё одно отличие генерации имён от стандартной обработки шаблона — в том, что символ «/», разделяющий элементы пути, никогда не ставится в соответствие «*» или диапазону. Происходит это не потому, что искажён алгоритм, а потому, что при генерации имён шаблон применяется именно к элементу пути, внутри которого уже нет «/». Например, получить список файлов, которые находятся в каталогах /usr/bin и /usr/sbin и содержат подстроку «ppp» в имени, можно с помощью шаблона «/usr/*bin/*ppp*». Однако одного шаблона, который бы включал в этот список ещё и каталоги /bin и /sbin — то есть подкаталоги другого уровня вложенности — по стандартным правилам сделать нельзя.

Генерация имён файлов в zsh предусматривает специальный шаблон «**», которому соответствуют подстроки с любым количеством «/». Пользоваться им следует крайне осторожно, понимая, что при генерации имён по такому шаблону выполняется операция, аналогичная не ls, а ls -R или find. Так, использование «/**» в начале шаблона вызовет просмотр всей файловой системы!

Если перед любым специальным символом стоит «\», этот символ лишается специального значения, экранируется: пара «\символ» заменяется командным интерпретатором на «символ» и передаётся в командную строку безо всякой дальнейшей обработки:

[methody@localhost methody]$ echo *o*
 Documents loop to.sort
[methody@localhost methody]$ echo \*o\*
 *o*
[methody@localhost methody]$ echo "*o*"
 *o*
[methody@localhost methody]$ echo *y*
 *y*
[methody@localhost methody]$ ls *y*
 ls: *y*: No such file or directory

Пример 8. Экранирование специальных символов и обработка «пустых» шаблонов

Мефодий заметил, что шаблон, которому не соответствует ни одного имени файла, bash раскрывать не стал, как если бы все «*» в нём были экранированы. В самом деле, какое из двух зол меньшее: изменять интерпретацию спецсимволов в зависимости от содержимого каталога, или сохранять логику интерпретации с риском превратить команду с параметрами в команду без параметров? Если бы, допустим, шаблон, которому не нашлось соответствия, попросту удалялся, то команда ls *y* превратилась бы в ls и неожиданно выдала бы содержимое всего каталога. Авторы bash (как и Стивен Борн, автор самой первой командной оболочки — sh) выбрали более непоследовательный, но и более безопасный первый способ.

вторы zsh пошли по другому пути: в этой версии shell использование шаблона, которому не соответствует ни одно имя файла, приводит к ошибке, и соответствующая команда не выполняется.

Лишить специальные символы их специального значения можно и другим способом. В лекции Терминал и командная строка было рассказано, что разделители (пробелы, символы табуляции и символы перевода строки) перестают восприниматься таковыми, если часть командной строки, их содержащую, окружить двойными или одинарными кавычками. В кавычках перестаёт «работать» и генерация имён (как это видно из примера), и интерпретация других специальных символов. Двойные кавычки, однако, допускают выполнение подстановок переменной окружения и результата работы команды, описанных в двух следующих разделах.

Перекрёстные ссылки книги для Генерация имён файлов

  • Редактирование ввода
  • Вверх
  • Окружение

Book navigation

  • Предисловие
  • Сеанс работы в Linux
  • Терминал и командная строка
  • Структура файловой системы
  • Работа с файловой системой
  • Доступ процессов к файлам и каталогам
  • Права доступа
  • Работа с текстовыми данными
  • Возможности командной оболочки
    • Редактирование ввода
    • Генерация имён файлов
    • Окружение
    • Язык программирования sh
    • Настройка командного итерпретатора
  • Текстовые редакторы
  • Этапы загрузки системы
  • Работа с внешними устройствами
  • Конфигурационные файлы
  • Управление пакетами
  • Сеть TCP/IP в Linux
  • Сетевые и серверные возможности
  • Графический интерфейс (X11)
  • Прикладные программы
  • Политика свободного лицензирования

Последние материалы

  • Файл sudoers
    10 hours 43 minutes ago
  • Утилита visudo
    1 day 18 hours ago
  • Файловый менеджер Thunar
    1 week 4 days ago
  • Эмулятор терминала Terminator
    2 weeks 2 days ago
  • Приложение scanimage
    3 weeks 1 day ago
RSS feed

Secondary menu

  • О проекте

© 2008–2025 Олег Меньшенин mensh@yandex.ru