Главная » Программирование для UNIX » Сокращения в именах файлов UNIX

0

Начнем  с  шаблона  имени  файла.  Предположим,  требуется  ввести большой  документ, например книгу. Логически книга  разделена на небольшие фрагменты: главы и, может быть, разделы. Физически ее также надо разделить, ведь  большие файлы неудобно редактировать.

Поэтому документ должен быть  записан по частям в несколько фай лов.  Можно  создать отдельный файл для  каждой главы и назвать их ch1, ch2 и т. д. Если же каждая глава разбита на разделы, то можно создать файлы:

ch1.1 ch1.2 ch1.3

… ch2.1 ch2.2

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

Какие действия надо предпринять, чтобы напечатать книгу целиком?

Можно сказать:

$ pr  ch1.1  ch1.2  ch1.3  …

но вводить имя за именем скоро  надоест, к тому же, в длинном списке легко наделать ошибок.  На  помощь приходит маска имени файла. Вводим:

$ pr  ch*

Для оболочки символ * означает любую строку символов, так что ch* – это шаблон, которому соответствуют имена всех файлов в текущем каталоге, начинающиеся с ch. Оболочка создает список таких файлов в алфавитном порядке1 и передает этот список программе pr. Программа pr не видит никаких *, ей передается список строк, которые оболочка нашла в текущем каталоге по совпадению с шаблоном.

Решающим является то,  что  маска файла – это не свойство команды pr, а сервис  оболочки. То есть ее можно использовать для  образования последовательности имен  файлов в любой команде. Например, чтобы  сосчитать количество слов в первой главе:

$ wc ch1.*

113

562

3200 ch1.0

935

4081

22435 ch1.1

974

4191

22756 ch1.2

378

1561

8481 ch1.3

1293

5298

28841 ch1.4

33

194

1190 ch1.5

1        Еще  раз  обратим ваше  внимание на то, что порядок сортировки не строго  алфавитный, буквы в верхнем регистре предшествуют буквам в нижнем. См. ascii(7) относительно упорядочения сортируемых символов.

75        323      2030  ch1.6

3801    16210    88933  total

$

Есть  такая команда echo, которая чрезвычайно полезна для проверки значений символов маски. Легко догадаться, что делает эта команда – она «отражает» (выводит) свои аргументы:

$ echo hello  world

hello  world

$

Но ведь аргументы могут быть заданы шаблоном:

$ echo ch1.*

выводит имена всех файлов главы 1,

$ echo *

выводит имена всех  файлов текущего каталога в алфавитном порядке,

$ pr  *

распечатывает все файлы (в алфавитном порядке) и, наконец,

$ rm *

удаляет все файлы в текущем каталоге. (Надо было убедиться, что это

действительно то, что вы хотели!)

Символ * не обязательно должен занимать последнюю позицию в имени файла, таких символов может быть несколько и они могут стоять в любом месте. Так,

$ rm *.save

удаляет все файлы, имена которых оканчиваются на .save.

Учтите, что имена файлов отсортированы в алфавитном, а не в числовом порядке. Поэтому если  в книге 10 глав, то порядок вывода может оказаться не таким, как вы ожидали, – ch10 предшествует ch2:

$ echo *

ch1.1  ch1.2  … ch10.1  ch10.2  … ch2.1 ch2.2  …

$

Хотя  шаблон, образованный с помощью *, и применяется чаще  всего, имейте в виду, что оболочка может обрабатывать и другие шаблоны. Шаблону  […] удовлетворяет  любой  из  символов, находящийся  в скобках. Ряд  последовательных букв  или  цифр может быть  записан в краткой форме:

$ pr  ch[12346789]*       Печатать главы 1,2,3,4,6,7,8,9, но не 5

$ pr  ch[1-46-9]*            То же, что и в первом случае

$ rm temp[a-z]             Удалить любые существующие tempa, …, tempz

Шаблону ? соответствует любой отдельный символ:

$ ls ?                Перечисляет файлы с именами из одного символа

$ ls -l ch?.1   Выводит ch1.1  ch2.1  ch3.1 и т. д., но не ch10.1

$ rm temp?         Удаляет файлы temp1, …, tempa и т. д.

Обратите внимание, что шаблоны относятся только к существующим именам файлов. В частности, нельзя при  помощи шаблонов создавать новые  имена. Например, если  надо  в  названии каждого файла заме нить сокращение сh на слово chapter, то нельзя сделать это командой:

$ mv  ch.*  chapter.*        Не работает!!!

потому что не существует файлового имени, соответствующего шаблону chapter.*.

Шаблонные символы, такие как *, могут применяться как в простых именах файлов, так и в путевых; в этом  случае соответствие опреде ляется  для   каждого компонента  пути,  содержащего специальный символ. То есть /usr/mary/* совпадает со всем содержимым /usr/mary, а

/usr/*/calendar  генерирует список путевых имен файлов calendar всех пользователей.

Если  символы *, ? и т. д. интересуют вас сами  по себе, в отрыве от своего специального значения, заключите весь аргумент в одинарные кавычки, как в нижеследующем примере

$ ls ‘?’

Также можно предварить специальный символ обратной косой  чертой:

$ ls \?

(Поскольку ?  – это не символ аннулирования строки и не знак исключения, то такая  обратная косая черта интерпретируется не  ядром, а оболочкой.) Применение кавычек подробно обсуждается в главе 3.

Упражнение 1.4. В чем состоят отличия между этими командами?

$ ls junk           $ echo junk

$ ls /           $ echo /

$ ls              $ echo

$ ls *                $ echo *

$ ls ‘*’        $ echo ‘*’

~

Источник: Керниган Б., Пайк Р., UNIX. Программное окружение. – Пер. с англ. – СПб: Символ-Плюс, 2003. – 416 с., ил.

По теме:

  • Комментарии