Неинтерактивный текстовый редактор SED
Галина О. В., Суперкомпьютерный Центр
1. Назначение и Формат использования
SED - неинтерактивный текстовый редактор, предназначенный для пакетного редактирования файлов. Полезен для:
- Редактирования очень больших файлов;
- Редактирования файлов любой величины, если последовательность команд редактирования является слишком длинной и сложной и, следовательно, неудобной для выполнения интерактивного редактирования.
- Выполнения множества раз одной и той же функции редактирования.
SED копирует строку из input (стандартный или указываемый набор файлов) в PATTERN SPACE (некоторая область), и к этой строке применяет все команды, адреса которых попадают в PATTERN SPACE . Затем PATTERN SPACE копируется в output. (Фактически в PATTERN SPACE находится одна строка, за исключением команды N , см.4. Функции SED )
Формат:
SED [-n] [-e script] [-f sfile] [files]
script - набор команд редактирования SED , который может содержать до 200 команд или до 10000 байт.
sfile - файл со скриптом SED .
files - файлы, предназначенные для SED -редактирования.
-n - указывает, что в output выводятся не все строки, но только те, к которым применялась команда p. (См. 4.Функции SED и 5.Функция контекстной замены.)
Флаг -e может быть опущен, если он присутствует один.
Команда SED :
[address[,address]] function [arguments]
2. Адресация в командах SED
С помощью адресации происходит отбор строк для редактирования.
Адрес:
- Десятичный номер строки;
- $ - последняя строка input;
- Регулярное выражение.
Если адреса не указаны, то команда применяется ко всем pattern space;
Если присутствует один адрес, то команда применяется ко всем тем pattern space, куда попадает этот адрес;
Если указаны два адреса, то они ограничивают область применения команды.
3. Регулярное выражение
Для осуществления отбора строк для редактирования, в адресах команд SED допускается использование регулярных выражений, заключенных в "/ /" и определяемых следующим образом:
- Регулярное выражение указывается в разделителях: "/ /" ;
- любой символ (кроме специальных: \[.^*$] является регулярным выражением себя;
- ^ в начале регулярного выражения указывает на пустой символ в начале регулярного выражения. (Т.е. на начало строки)
- $ в конце регулярного выражения указывает на пустой символ в конце регулярного выражения. (Т.е. на конец строки);
- \n - вставленный newline (новая строка);
- . - любой символ (кроме обыкновенного newline);
- - стоящая за регулярным выражением означает любую последовательность вхождений этого выражения, начиная с 0;
- [ ] - указывает на один из символов, приведенных внутри;
- [^ ] - указывает на один из символов, кроме приведенных внутри;
- \ - перед любым символом, кроме цифр и "(" , ")" , означает этот символ. ( Экранирование специальных символов).
- \(x\) -, где x - регулярное выражение, указывает на x .
- \d -, где d - цифра, указывает копию d -го выражения, которое заключалось в скобки "\(" и "\)" ;
- конкатенация регулярных выражений является регулярным выражением.
Примеры:
/olga/ - указывает на строки содержащие "olga" , "abcolgadef" , ...;
/ol.*ga/ - указывает на строки, содержащие "olga" , "olabcga" , ...;
/^[Oo]lga/ - на строки, начинающиеся с "Olga" или "olga" ;
/./ - попадают все строки, имеющие хотя бы 1 символ (не newline);
/\./ - попадают строки, содержащие "." ;
/^[^ ]/ - строки, не начинающиеся с " "
/\(ol\).*\1/ - строки, содержащие два вхождения "ol" не подряд.
4. Функции SED
(В скобках указывается максимальное число адресов)
(1) a \text - Добавить "text" после указанной строки (вывести), потом считать следующую.
(2) b label - Перейти на метку, устанавливаемую, с помощью функции ":" , если label пуст, то перейти в конец скрипта.
(2) c \text - Удалить pattern space и вывести "text" на output.
(2) d - Удалить pattern space .
(2) D - Удалить pattern space до вставленной newline.
(2) g - Заместить содержимое pattern space содержимым буфера hold space.
(2) G - Добавить к содержимому pattern space содержимое буфера hold space .
(2) h - Заместить содержимое буфера hold space на содержимое pattern space .
(2) H - Добавить к содержимому буфера hold space содержимое pattern space .
(1) i \text - Вывести текст на output перед указанной строкой.
(2) n - Вывести pattern space на output и считать следующую строку.
(2) N - Добавить следующую строку к pattern space , разделяя строки вставленным newline.
(2) p - Скопировать pattern space на output.
(2) P - Скопировать pattern space до первой вставленной newline на output.
(1) q - Переход на конец input. Вывести указанную строку, (если нет флага -n) и завершить работу SED .
(2) r rfile - Читать содержимое rfile и вывести его на output прежде чтения следующей строки.
(2) s - Функция контекстной замены. (См. 5.)
(2) t label - Перейти на метку, устанавливаемую с помощью функции ":" , если для этой строки была осуществлена замена с помощью функции "s" . Флаг осуществления замены восстанавливается при чтении следующей строки или при выполнении функции "s".
(2) w wfile - Добавить pattern space к концу файла wfile. (Максимально можно использовать до 10 открытых файлов.)
(2) x - Поменять местами содержимое pattern space и буфера hold space .
(2) y /str1/str2/ - Заменить все вхождения символов из str1 на соответствующие из str2. Длины строк должны быть равными.
(2) ! func - Применять функцию func (или группу функций в {}) к стокам НЕ попадающим в указанные адреса.
(0) : label - Устанавливает метку для перехода по "b" и "t" командам.
(1) = - Выводит номер строки на output как строку.
(2) { - Выполняет функции до "}" , только когда выбрано pattern space . Группировка функций.
(0) - Пустая команда игнорируется.
# - Комментарий.
( "#n" в скрипте равносильно установке флага -n)
5. Функция контекстной замены
Формат:
(2)
s/<Регулярное выражение> /<Замена> /<флаги>
Функция s заменяет вхождение <Регулярного выражения> в pattern space на <Замену> .
<Регулярное выражение> : Аналогично выше данному, но может быть заключено не в "/ /" а в любые другие символы (не " " (пробел) и не newline).
<Замена> : Любой набор символов. Используются специальные символы:
"&" - Заменяется на строку, указанную в регулярном выражении.
"\d" - , где d - цифра, указывает на d-е выражение, заключенное в "\(","\)" в регулярном выражении.
<Флаги> :
g - Глобальная замена: заменить все вхождения в строке.
p - Печатать (выводить на output) строки, в которых была осуществлена замена.
w wfile - Выводить в файл wfile строки, в которых была осуществлена замена.
Примеры:
s/to/by/w changes - Заменить в тексте первое вхождение "to" в каждой строке, если таковое есть, на "by" и измененные строки сохранить в файле "changes".
/iiii/s/[Oo]lga/ Olga V.Galina/p - Заменить в тексте, в строках, где встречается вхождение "iiii" , первое вхождение подстроки "olga" или "Olga" на " Olga V.Galina" , при этом измененные строки выводить на печать.
s/[.,;:?]/*sign& *sign& **/g - Заменить в тексте каждое вхождение одного из знаков ".,;:?" в строку на "*sign& *" , где & будет тем знаком, который стоял прежде, например, "." на "*sign.* " , "?" на "*sign?* " и т. д.
6. Сравнительное решение задач с помощью SED и AWK
Система UNIX обладает несколькими утилитами, которые обрабатывают входной поток данных и позволяют также решать некоторые задачи редактирования: grep, egrep, fgrep, lex и awk. Мощная и многофункциональная утилита awk также может быть применена для простого редактирования текстов, поскольку также основана на использовании регулярных выражений. Однако, как видно из примеров, приведенных ниже, время решения задач с помощью sed значительно меньше по сравнению со временем, затрачиваемым awk. Неинтерактивный редактор sed обеспечивает выполнение в пакетном режиме большинства функций редактирования редактора ed и является оптимальным при решении несложных задач пакетного редактирования.
Примеры:
- Посчитать количество строк (input)
SED: $= (10.2 c.)
AWK: END { PRINT NR } (15.0 c.)
- Напечатать все строки, содержащие "olga"
SED: /olga/p (11.6 c.)
AWK: /olga/ (25.6 c.)
- Напечатать все строки, содержащие "olga", "mike" или "mal"
SED: /olga/p
/olga/d
/mike/p
/mike/d
/mal/p
/mal/d (15.8 c.)
AWK: /olga|mike|mal/ (29.9 c.)
- Напечатать третье поле каждой строки
SED: /[^ ]* [ ]*[^ ]* [ ]*\([^ ]*\).*/s//\1/p (29.0 c.)
AWK: {PRINT $3} (33.3 c.)
- Напечатать сначала третье а затем второе поля каждой строки
SED: /[^ ]* [ ]*\([^ ]*\) [ ]*\([^ ]*\).*/s//\2\1/p (30.5 c.)
AWK: {PRINT $3 $2} (38.9 c.)
- Добавить строки, содержащие "olga", "mike" или "mal" соответственно к файлам: folga, fmike, fmal
SED: /olga/w folga
/mike/w fmike
/mal/w fmal (16.1 c.)
AWK: /olga/ {print > "folga"}
/mike/ {print > "fmike"}
/mal/ {print > "fmal"} (46.4 c.)
Список команд