This is the Fl key:^[OP This is the F2 key:^[OQ
Так и есть! Это не буквы 'Р и 'Q', а управляющие символы, хотя и непонятно, с помощью каких клавиш они были сгенерированы.
Аналогичным образом будет вести себя и редактор sed при работе с данным; файлом. Если вы попытаетесь просмотреть его содержимое, будет выдано следующее:
$ sed -n '1,$p' func.txt
This is the F1 key:P This is the F2 key:Q
В редакторе существует команда l (list}, аналог рассмотренной выше команды cat -v. Формат команды l таков:
[адрес1[,адрес2]]l
Ее действие равносильно применению команды p, но при этом все непечатаемые символы заменяются восьмеричными ASCII–кодами (кроме того, длинные строки, выходящие за пределы экрана, разбиваются на части, а конец каждой строки помечается символом '$'). Вот что получится, если применить эту команду к файлу func.txt.
$ sed -n '1,$1' func.txt
This is the Fl key:\033OP$ This is the F2 key:\033OQ$
Теперь ситуация немного проясняется. По таблице ASCII–кодов можно узнать, что восьмеричный код 033 соответствует непечатаемому символу esc. Именно он в выводе команды cat -v обозначается как ^ [. За ним идут два обычных символа: сначала 'О', затем 'Р' либо 'Q'. Таким образом, мы имеем дело с двумя клавишами, каждая из которых сгенерировала трехсимвольную последовательность: одна — esc‑O–р, а вторая — esc‑o–q. Когда файл отображается в обычном режиме, каждому символу соответствует одно знакоместо, поэтому первые два символа последовательности отбрасываются и остается последний: 'P' и 'Q' соответственно.
Нет системной команды, которая позволяла бы узнать, какие клавиши генерируют эти коды. Подобные сведения находятся в базах данных termcap и terminfo, хранящих установки терминала, но знакомство с этими базами данных выходит за рамки нашей книги. Проще всего пойти экспериментальным путем: ввести команду cat или cat -v без указания входного файла, с тем чтобы попробовать самостоятельно определить, нажатия каких клавиш приводят к отображению на экране нужных последовательностей символов. В нашем случае последовательность ESC‑O–P генерируется клавишей [F1], а последовательность ESC‑O–Q — клавишей [F2], хотя в общем это зависит от установок терминала.
Если вам интересно, как можно создать файл func.txt, ниже описана возможная процедура:
1. Загрузите редактор vi.
2. Перейдите в режим вставки с помощью команды i и введите первую строку файла вплоть до двоеточия.
3. Нажмите [Ctrl+V], при этом появится символ '^'
4. Нажмите клавишу [F1], при этом отобразится последовательность [ор.
5. Нажмите клавишу [Enter] и повторите пункты 2—4 для второй строки файла (в конце нажимается клавиша [F2]).
6. Нажмите клавишу [Esc], чтобы выйти из режима вставки.
7. Введите команду w func.txt, чтобы сохранить файл.
8. Введите команду q, чтобы выйти из редактора vi.
10.16. Дополнительные примеры использования редактора sed
Выше были описаны основные команды sed. Далее мы рассмотрим ряд практических примеров применения редактора sed.
Одной из задач, для которых редактор sed используется весьма часто, является удаление управляющих, непечатаемых и просто посторонних символов из файлов, которые были загружены из других систем. Ниже приведен фрагмент подобного файла dos.txt.
$ cat -v dos.txt
12332##DISO##45.12^M C0332##LPSO##23.11^M
01299##USPD##34.46^M
Вот что необходимо сделать:
1. Заменить все знаки решетки ('#'( пробелом.
2. Удалить из первого поля каждой строки все ведущие нули.
3. Удалить в конце каждой строки последовательность ^M, генерируемую непечатаемым символом CR — возврат каретки (ASCII–код 13).
Примечание:
В ряде систем, в которых мне приходилось выполнять подобные преобразования, в конце строки стоит символ перевода строки LF (ASCII–код 10, отображается как ^@). Подобная проблема нередко возникает при передаче файлов между двумя системами, в одной из которых символ новой строки (\n) заменяется последовательностью CR/LF, a в другой — только одним из этих двух управляющих символов.
Задача 1. Удаление всех символов решетки реализуется без особого труда. Для этого достаточно выполнить команду замены s с флагом глобальной подстановки д, указав при этом, что один или более символов '#', идущих подряд, должны быть заменены пробелом:
$ sed 's/##*/ /g' dos.txt | cat -v
12332 DISO 45.12^М
00332 LPSO 23.11^М
01299 USPD 34.4б^M
Задача 2. Для удаления всех ведущих нулей следует в команде s оставить шаблону замены пустым, а шаблон поиска задать таким: /^0*/. Он означает, что требуется найти любое количество нулей, стоящих в начале строки.