$ sed 's/^0*//' dos.txt | cat -v
12332##DISO##45.12^M
332##LPSO##23.11^M
1299##USPD ##34.46^M
Задана 3. Чтобы избавиться от управляющих символов ^M в конце строк, необходимо. также применить команду s, оставив шаблон замены пустым. А вот при формировании шаблона поиска следует учесть, что мы имеем дело с непечатаемым символом. Нельзя просто ввести символы '^' и 'M', так как полученный шаблон будет означать, что мы ищем букву 'М', стоящую в начале строки. Чтобы действительно создать нужный нам непечатаемый символ, необходимо нажать [Ctrl+V], а затем — клавишу [Enter]. Результат будет выглядеть как регулярное выражение ^M, но на самом деле это экранное представление символа CR.
$ sed 's/^M//' dos.txt | cat -v
12332##DIS0##45.12 0D332##LPSO##23.11 01299##U5PD#t34.46
Теперь можно попробовать объединить три команды в одну с помощью опции -e;
$ sed -e 's/^0*//' -e 's/^M//' -e 's/##*/ /g' dos.txt | cat -v
12332 DISO 45.12
332 LPSO 23.11
1299 USPD 34.46
Выходные данные редактора sed передаются по каналу команде cat -v, которая позволяет убедиться, что вся работа, включая удаление непечатаемых символов, выполнена правильно.
Приведенные выше команды удобнее поместить в файл сценария. Назовем его dos.sed. Вот его текст:
$ cat dos.sed
#! /bin/sed -f
#Имя: dos.sed
#Командная строка: dos.sed dos.txt
#Избавляемся от символа решетки
s/##*/ /g
#Удаляем ведущие нули
s/^0*//
#Удаляем символы возврата каретки
s/^M//
На входе данного сценария следует указать файл dos.txt. Сценарий "исправит" этот файл и выведет результат на экран. Если же ввести следующую командную строку:
$ dos.sed dos.txt | tee dos.txt
то результат будет записан обратно в файл dos.txt.
Я часто сталкиваюсь с необходимостью форматировать данные, возвращаемые инструкциями SQL. Для этого приходится писать комплексные сценарии, в которых сразу несколько текстовых фильтров выполняют работу совместно. Рассмотрим результаты выполнения некоторой инструкции SQL, выполняющей обращение к одной из таблиц базы данных:
Database | Size (MB) | Date created |
GOSOUTH | 2244 5632 | 12/11/9? 8/9/99 |
TRISUD |
(2 rows affected) Из этой информации нас, предположим, интересуют только имена баз данных, находящиеся в первой колонке. Чтобы их извлечь, необходимо выполнить следующую последовательность действий:
1. Удалить пунктирную линию с помощью команды s/--*//g.
2. Удалить все пустые строки с помощью команды /^$/d.
3. Удалить последнюю строку с помощью команды $d.
4. Удалить первую строку с помощью команды 1d.
5. Отобразить первый столбец с помощью команды awk '{print $1}'. Ниже приведена соответствующая цепочка команд:
$ sed 's/--*//g' -e '/^$/d' -e '$d' -e '1d' sql.txt | awk '{print $1}'
GOSOUTH TRISUD
В процессе потоковой обработки файла мне иногда требуется добавить к каждой проверенной строке какой‑нибудь текст, сообщающий о том, как прошла обработка. Предположим, имеется такой файл:
$ cat ok.txt
АС456
АС492169
АС9967
АС88345
Наша задача состоит в добавлении слова "Passed" (обработано) в конец каждой строки. Решить ее несложно. Достаточно в шаблоне поиска указать метасимвол '$', означающий конец строки, а в шаблоне замены — пробел и искомое слово:
$ sed 's/$/ Passed/' ok.txt
АС456 Passed
АС492169 Passed
AC9967 Passed
AC8B345 Passed
Ниже показано, как с помощью редактора sed можно быстро удалить начальную косую черту из имени текущего каталога:
$ cd /usr/local
$ echo $PWD | sed 's/^\///g'
usr/local
Имя текущего каталога хранится в переменной среды Spwd. Эта переменная обновляется всякий раз, когда выполняется команда cd. Команда echo передает значение переменной по каналу редактору sed, который выполняет несложную обработку: находит в начале строки (метасимвол '^'( символ косой черты (защищен от интерпретации обратной косой чертой) и заменяет его пустой подстрокой.
10.17. Заключение
Редактор sed является эффективным инструментом фильтрации текста. Он дает возможность находить во входном потоке требуемые строки и последовательности символов и модифицировать их с наименьшими затратами времени и усилий. Как было показано, для извлечения из файлов требуемой информации вовсе не обязательно прибегать к написанию больших сценариев.