Лекция Зачем спо в школе?

Вид материалаЛекция

Содержание


Лекция 13. Выражайтесь правильно!
Ориентация на построчную структуру
Нечеткая интернационализация
13.1 “Глоббинг” (шаблоны имен файлов в оболочке)
Подобный материал:
1   ...   12   13   14   15   16   17   18   19   ...   22

Лекция 13. Выражайтесь правильно!


В ОС UNIX, послужившую прототипом для современных открытых систем, изначально были встроены мощные средства работы с текстом. Это было связано с тем, что ее первыми основными приложениями были программирование (включающее порой весьма изощренную работу с исходными текстами) и обработку патентной информации в корпорации AT&T (тоже, естественно, представленной в текстовом виде).

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

Ориентация на построчную структуру. Действительно, вплоть до начала девяностых основная масса обрабатываемой текстовой информации была представлена в виде “плоского” (неразмеченного) текста с построчной структурой. Распространенные стили программирования на большинстве языков также предполагают построчное разбиение как средство оформления исходных текстов. В таких условиях построчная обработка обычно предоставляет достаточно осмысленный контекст для поиска, выбора и т.п. текста.

Сегодня же текст (на естественном языке) все чаще представлен в размеченном на том или ином языке разметки (таком, как XML, HTML или TeX), при этом построчное разбиение (символами конца строки) может отсутствовать или носить технический (случайный по отношению к логической структуре) характер. Более того, текстовая информация может быть представлена логически также в принципиально нелинейном виде (например, в виде таблицы).

При всей справедливости этого замечания, ориентация на построчное разбиение заложена лишь в некоторые системные утилиты (например, семейства grep), а большинство утилит может использоваться и с размеченным текстом. Более того, распространенные языки разметки имеют на первом уровне достаточно простой синтаксис, позволяющий с помощью тех же стандартных утилит “отделить мух от котлет” (метки от размечаемого текста). Например, в HTML метки всегда заключены в пару символов < и >, а спецсимволы — в пару & и ;. Все остальное является текстом, и задачу его выделения из html мы решим в ходе этой “лекции”.

Нечеткая интернационализация. В СССР и Россию открытые системы попали изначально в практически не локализованном виде. Многие операции (даже такие простые, как алфавитная сортировка) применительно к кириллическому тексту теряли осмысленность.

Сегодня в распространенных открытых системах (большинство сборок UNIX, GNU/Linux, *BSD) поддерживается корректная интернационализация и локализация с использованием восьмибитных кодовых таблиц символов. В отношении кодировки Unicode с некоторыми утилитами до сих пор возможны проблемы (а Unicode является единственным практичным способом работы, например, с немецко-русскими или украинско-французскими двуязычными текстами, не говоря уже о восточных алфавитах и многоязычных текстах), несмотря на то, что поддержка Unicode-локалей{Локаль (locale) — определение текущего окружения, относящегося к естественно-языковым и культурно-конвенциональным аспектам, таким, как алфавит и его порядок, язык вывода сообщений, формат даты и времени и т.п.} включена в текущую версию стандарта на оболочку и утилиты.

13.1 “Глоббинг” (шаблоны имен файлов в оболочке)


Поддержка зачаточных регулярных выражений оболочкой ОС называют иногда “глоббингом”. “Глоббинг” (шаблоны) — это выражения, встречающиеся в командной строке и содержащие определенные символы, каковые выражения оболочка интерпретирует как шаблоны имен файлов и подменяет списком файлов, имена которых совпадают с этими шаблонами. Важно понимать, что эту процедуру (иногда называемую распространением (expanding) неоднозначного имени или генерацией имен по шаблону) выполняет именно оболочка, а не вызываемая утилита.

Звездочка. Звездочка означает любую последовательность символов (включая пустую). Например, исполнение команды ls a* в каталоге, содержащем файлы aa, ab, ba, bb, будет полностью эквивалентно исполнению команды ls aa ab, а не передаче утилите ls команды 'a*'. Собственно, можно попробовать передать утилите такую строку, заключив ее в одинарные кавычки (апострофы) — такие кавычки “экранируют” специальные символы от интерпретации оболочкой. Результат предстказуем — ls сообщит, что файла с именем, состоящим из буквы a и звездочки, в текущем каталоге нет (Рис. 1).

$ ls

aa ab ba bb


$ ls a*

aa ab


$ ls 'a*'

ls: a*: No such file or directory


Рис 1

Вопросительный знак. Кроме звездочки, означающей “ноль или более любых символов”, стандартная оболочка распознает символ ? (вопросительный знак) — один символ. Например, исполнение команды ls ?a будет эквивалентно ls aa ba.

Предположим, в отдельном каталоге размещены тексты предшествоваших лекций этой серии в файлах, поименованных с 1.txt по 12.txt, а кроме того, файл toc.txt содержит оглавление содержания этих лекций. Мы хотим вывести список файлов с лекциями, соответствующий “естественному” порядку их следования. Однако команде ls он неизвестен, она (по умолчанию) перечисляет имена в порядке их алфавитного следования (в котором 10.txt предшествует 2.txt). Как быть? Мы можем попробовать дать команду ls ?.txt ??.txt в надежде получить сначала имена, в которых точке предшествует один символ (однозначные номера лекций), а затем имена, в которых точке предшествует два символа. Однако результат может обескуражить (см. рис. 2). Дело в том, что утилита ls сама сортирует имена всех найденных файлов уже после того, как их сравнение с шаблоном завершено.

Обойти это мы можем, отказавшись от утилиты ls и прибегнув к утилите echo (которая, как известно, просто выводит на экран свои аргументы), пользуясь знанием о том, что оболочка сама расширяет неоднозначные имена. Теперь “однозначные номера” предшествуют двузначным.

$ ls

1.txt 11.txt 2.txt 4.txt 6.txt 8.txt book.txt

10.txt 12.txt 3.txt 5.txt 7.txt 9.txt toc.txt


$ ls ?.txt ??.txt

1.txt 11.txt 2.txt 4.txt 6.txt 8.txt

10.txt 12.txt 3.txt 5.txt 7.txt 9.txt


$ echo ?.txt ??.txt

1.txt 2.txt 3.txt 4.txt 5.txt 6.txt 7.txt 8.txt 9.txt 10.txt 11.txt 12.txt


Рис. 2


Скобочные выражения. И наконец, третий элемент “глоббинга” — это списки и диапазоны символов. Заключенная в квадратные скобки последовательность символов означает образец, которому соответствует хотя бы один из этих символов. Например, образцу [135].txt соответствует список файлов 1.txt 3.txt, 5.txt. Кроме списков, в квадратных скобках могут присутствовать диапазоны — пары символов, разделенные дефисом. Такому образцу соответствует любой символ, попадающий в указанный диапазон (имея в виду алфавитный порядок символов).

Применение “глоббинга”. Допустим, мы решили объединить лекции в части будущей книги, пользуясь для этого командой объединения файлов cat. В нашем примере команда cat [1-5].txt >part1.txt “сольет” в файл part1.txt файлы 1.txt, 2.txt, 3.txt, 4.txt и 5.txt.

Однако, “слить” следующие пять файлов во вторую часть командой cat [6-10].txt >part2.txt уже не удастся. Почему? — Ведь оболочке неведомо, что цифры 10 означают для нас число 10. Она проинтерпретирует выражение [6-10].txt как “символ в диапазоне 6-1 или совпадающий с 0, за каковым символом следуют символы .txt”. Понятно, что в диапазон 6-1 ничего не попадает (поскольку 6 алфавитно следует за 1, а не предшествует ему), а файла с именем 0.txt в нашем примере нет, так что образцу в целом будет соответствовать пустое множество файлов. Придется нам объединять файлы более сложной командой cat [1-9].txt 10.txt >part2.txt.

“Слить” в третью часть два оставшихся файла просто: cat 1[12].txt >part3.txt (или полностью равнозначной ей командой cat 1[1-2].txt >part3.txt). И, наконец, собрать части в книгу, предварив ее оглавлением, мы можем с помощью команды cat toc.txt part[1-3].txt >book.txt.

Если бы эти “лекции” продолжались не один учебный год, а года три, и у нас скопилось 37 файлов, объединить их в книгу мы смогли бы командой cat [1-9].txt [12][0-9].txt 3[0-7].txt >book.txt{Жизнь, конечно, становится много проще, если использовать нумерацию с разрядностью, соответствующей количеству файлов, добавляя при необходимости ведущие нули: 01.txt, 02.txt и т.д.}.