Выберите верные способы замены одного символа другим

Инструменты для перевода и управления текстом

На заре истории UNIX® люди, работавшие с этой новой операционной системой, быстро нашли нишу, которую смогли заполнить; людям в университетах требовалась подходящая среда обработки текстов. Из-за скорости обработки данных и количества памяти в компьютерах в те дни программы должны были быть небольшими и относительно простыми. Это привело к знаменитой философии проектирования UNIX: «набор средств, работающих совместно над одним заданием.» При помощи комбинирования нескольких небольших, но мощных инструментов обработки текста в каналы UNIX pipes, текст может быть преобразован и обработан несметным числом способов.

Прежде, чем начать

Синтаксис оболочки, использованный здесь в примерах, подходит к GNU Bash; пожалуйста, выясните в руководстве по вашей оболочке особый синтаксис, который вам потребуется (или подумайте над тем, чтобы переключиться в Bash, как я полагаю).

Прежде чем начать управлять текстом при помощи нескольких текстовых утилит из всего многообразия UNIX, вам потребуется узнать, как добраться до какого бы то ни было текста. И прежде чем это сделать, вам потребуется освоить потоки стандартного ввода/вывода UNIX.

Когда вы перенаправляете вывод программы в файл при помощи оператора > в оболочке, вы посылаете поток ее стандартного вывода (stdout) в файл. Например: ls > this-dir посылает вывод ls в файл с именем this-dir.

Другой общий оператор для перенаправления стандартных потоков — это оператор | (pipe), который связывает поток стандартного вывода программы слева с потоком стандартного ввода программы справа. Например: ls | sort делает то же, что и предыдущие два примера, не требуя временного файла; вывод ls проходит напрямую через команду sort.

Перенаправляйте поток стандартных сообщений об ошибке в файл при помощи оператора 2>. Чаще всего вы это будете видеть, работая с командами, выводящими содержательные сообщения об ошибке, такими как инструмент make, используемый для сборки программ под UNIX: make 2> build-errors.

Если вас интересуют неприукрашенные детали, у других потоков также есть номера, хотя они почти никогда не используются (0 — это стандартный ввод, а 1 — стандартный вывод), за исключением одного на удивление обыкновенным оператором. В примере, приведенном в Листинге 1, оператор 2>&1 привязывает поток стандартных сообщений об ошибке к потоку стандартного вывода. В комбинации с оператором > вы получите stderr и stdout в одном и том же файле.

Наконец, команды

Команда cat считывает каждый из файлов, указанных в ее аргументах, и выводит содержимое файлов в stdout. Команда echo выводит в stdout свои аргументы. Вы будете часто их видеть в качестве части более сложной командной pipe-строки (см. Листинг 2).

Но что, если вы хотите получить только первую часть файла, или последнюю? Есть два варианта cat под названиями head и tail (см. Листинг 3), которые сделают то, что вы хотите, выводя первые или последние десять строк, соответственно (для обеих команд вы можете указать другое количество строк при помощи опции-n).

У команды tail есть другая удобная опция -f (англ. follow, сопровождать). Она сообщает tail печатать последние десять строк указанного файла, но, вместо того, чтобы завершаться, она ждет, что в файле появится больше текста, и печатает его, как только он появляется. Это можно использовать, чтобы сопровождать вывод в журнал ошибок, к примеру, чтобы увидеть, какие ошибки появляются в момент, когда они записываются в журнал.

Теперь, когда вы знаете, по крайней мере, пять различных способов порождения текста, рассмотрим то, как делаются некоторые простые его в нем.

Листинг 4. Как использовать tr, чтобы переводить символы

Взглянув на вывод этих команд (см. Листинг 5), вы получите ключ к тому, как работает tr (подсказка: это прямая замена символов из первого набора соответствующими символами из второго).

Первый и второй примеры достаточно просты: один символ заменяется другим. Третий пример, с опцией -d (англ. delete, удаление), полностью удаляет указанные символы из вывода. Это часто используется для удаления символов возврата каретки из текстовых файлов DOS, чтобы превратить их в текстовые файлы UNIX (см. Листинг 6). Наконец, в последнем примере применяются классы символов (эти имена в [: :]), чтобы конвертировать все буквы в нижнем регистре в буквы в верхнем регистре. Классы символов стандарта интерфейса переносимой операционной системы Portable Operating System Interface (стандарта POSIX) включают в себя:

Листинг 6. Преобразование текстовых файлов DOS в текстовые файлы UNIX

Хотя команда tr принимает команды среды локали C (посмотрите man locale, чтобы получить о них больше информации), не ожидайте от нее, что она сделает что-либо ощутимое с документами в кодировке UTF-8, — например, сможет заменить символы с диакритиками в нижнем регистре соответствующими символами в верхнем регистре. Команда tr лучше всего работает с ASCII и другими стандартными локалями C.

Возможности односимвольной замены (или удаления), предоставляемые командой tr, велики в особых случаях, но не очень гибки. Что, если вам требуется заменить одно слово другим, или ряд пробелов и символов табуляции одним пробелом?

Основной формат команды sed показан в Листинге 7. Шаблон (pattern) — это регулярное выражение, используемое для поиска совпадений во входном потоке (обычно либо перенаправленном из другой программы, либо из текстового файла), а замена (replacement) — это текст, который следует вставить вместо текста, совпавшего с шаблоном. Флаги (flags) — это одиночные символы, контролирующие поведение этой подстановки. Самый часто используемый флаг — это g (применить замену ко всем непересекающимся экземплярам, которые совпадают с шаблоном, вместо того, чтобы применить ее только к первому совпадению).

Listing 7. Команда sed

Самый простой шаблон — это просто строка из одного или нескольких символов. В Листинге 8, например, одно слово заменяется другим.

Вы можете поставить один или несколько символов в квадратные скобки, чтобы создать множество; любой символ из этого множества совпадет. Заменим все гласные на символы подчеркивания (см. Листинг 9).

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

Листинг 10. Поиск совпадений элемента именованного класса символов

Флаг -e команды echo указывает ей расширять escaped-символы стиля C; в данном случае он превратит \t в знак табуляции для вас.

Листинг 11. Это, вероятно, не то, что вы хотели

Теперь, когда самое основное вы уже увидели, рассмотрим несколько дополнительных модификаторов шаблонов; теперь вы станете также использовать опцию -E вместо -e, чтобы пользоваться усовершенствованными регулярными выражениями. Символ ? обозначает поиск нуля или одного соответствия предшествующему элементу шаблона; символ * означает поиск нуля или более соответствий предшествующему ему элементу. Символ + обозначает поиск одного или нескольких соответствий предшествующему элементу. Символ ^ соответствует началу строки, а $ — концу. Это можно увидеть в действии, как показано в Листинге 12.

Если вы поставите элементы шаблона в круглые скобки, то сможете использовать найденные совпадения в строке замены. Они называются группами; благодаря ним поиск регулярных выражений обретает высокую эффективность, но читаемость выражения в существенной степени затрудняется. Например, в Листинге 13 ищется один или несколько символов l (эль), за которыми следуют ноль или несколько символов o. Они заменяются содержимым второй группы, за которым следует первая, то есть, на самом деле, они меняются местами. Обратите внимание, что на группы следует указывать при помощи бэкслеша с номером группы в шаблоне.

Можно также осуществлять поиск соответствий специальному количеству повторений шаблона, указывая это количество в фигурных скобках. Например, шаблону o{2} будут соответствовать два (и только два) символа o.

Putting it together

Листинг 14. Типичный вывод ls -l

Как вы можете заметить, здесь есть семь колонок:

Создадим несколько регулярных выражений для выделения содержимого каждой из них:

В промежутках вам придется объединить все эти шаблоны записью [[:space:]]+, так как вы не знаете, разделены ли колонки пробелами, знаками табуляции, или же их комбинациями. Также вы захотите поместить права доступа, размер и имя в группы, чтобы иметь возможность использовать их в строке замены. Как видно из Листинга 15, регулярные выражения быстро становится трудно читать.

Если внимательно посмотреть на этот чудовищный шаблон регулярного выражения, можно обнаружить пять груп:

В Листинге 16, вывод ls -l заменяется так, что в итоге показывает имя файла, права доступа и размер.

Победа! Вы полностью изменили вывод.

Язык программирования и написания скриптов Perl (см. Ресурсы) часто применяется как в высшей степени мощная замена командам tr и sed, на которые вы только что смотрели. Короткая программа на Perl, часто вводимая непосредственно из командной строки, может иногда сделать больше, чем эквивалентная строка команды tr или sed.

В Листинге 17 показано, как дублировать примеры из Листинга 5 при помощи Perl.

Выражение Perl tr обладает слегка другим синтаксисом, более похожим на выражения поиска и замены sed. Также обратите внимание, что в последнем примере символы верхнего и нижнего регистров указаны при помощи диапазонов.

Листинг 18. Перестройка вывода ls при помощи Perl

Замечательно в этом то, что вы можете оттачивать ваши регулярные выражения как при помощи sed, так и Perl, и все равно использовать их в системах, в которых доступен либо только один из них, либо только другой. А в Perl в вашем распоряжении полный набор программных конструкций, которыми вы можете воспользоваться, осуществляя даже более сложную обработку текста.

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

Ресурсы для скачивания

Похожие темы

Источник

Поделиться:
Нет комментариев

Добавить комментарий

Ваш e-mail не будет опубликован. Все поля обязательны для заполнения.

×
Вам будет интересно