Программа редактирования, которую интерпретирует sed, состоит из одной или более команд редактирования, которые могут находиться как в командной строке, так и в файле, который указан в командной строке (параметры -e, -f, -expression, -file). В данном разделе мы будем иметь в виду одну программу или скрипт для═редактирования, который является сцеплением всех отдельных команд и скриптов редактирования упомянутых в командной строке (неважно непосредственно в строке или в файле).
Каждая команда редактирования состоит из следующих частей:
Адресация элементов текста может быть в одной из нижеследующих форм:
1~2
. А если вы хотите выбрать каждую третью строку
начиная со 2-ой строки, то следует использовать 2~3
.
Если вы захотите указать каждую пятую строку начиная с 10-ой, то
- 10~5
.
Наконец, странное выражение 45~0
будет означать 45-ую строку.
/
), то следует использовать комбинацию \/
.
Если не указано никакого адреса, то все строки вводного потока подвергаются действию команд(ы) редактирования. Если имеется один адрес, то лишь те строки подвергается действию команд редактирования, которые удовлетворяют адресу.
Адресный интервал может быть обозначен как пара адресов, раздел©нных запятой. Адресный интервал включает все строки вводного файла включительно начиная со строки, соответствующей первому адресу, до строки, соответствующей второму адресу. Если второй адрес является регулярным выражением regexp, тогда проверка на соответствие начн©тся со строки следующей за первым адресом. Если второй адрес есть целое n, которое меньше или равно первому адресу, то лишь одна строка будет считаться соответствующей адресному интервалу.
Добавление символа ! (восклицательный знак) в конце адресной спецификации означает отрицание значения соответствия. Таким образом, если знак ! следует после адресного интервала, то вс© выражение будет означать все строки не попадающие в адресный интервал.
sed использует два буфера для обработки вводного потока: основной буфер обработки (PATTERN BUFFER) и дополнительный буфер (HOLD BUFFER). В обычном режиме sed читает строки вводного потока и помещает из в основной буфер; там же производятся операции редактирования. дополнительный буфер изначально пуст, но ряд команд позволяют перемещать данные из одного буфера в другой.
SPMlt;NL>;).
Предупреждение:
В первой строке скрипта sed два символа идущие подряд #n имеют специальное значение: будет включн режим no-autoprint.
Значение replacement может содержать выражения вида \n
, где
n есть целое от 0 до 9. Такое выражение означает ту порцию
соответствия, которая заключена в n
-ные по порядку специальные
скобки вида \(
и \)
. Кроме этого, внутри выражения replacement может содержаться символ &
, который ссылается на
полную подстроку соответствующую regexp в основном буфере. Если вы
хотите ввести
в replacement литеральные символы SPMamp;;,
\n
или \
,
то следует использовать перед ними знак \
(обратный слеш).
Пример:
$ echo "Жужжали" | sed -n 's/Жуж/Гуж<&>/p' Гуж<Жуж>жалиЕщ© пример:
$ echo "Жужжали Бабочки" | sed -n 's/\(жж\)\(али\)/Гуж<&>\2\1/p' ЖуГуж<жжали>алижж Бабочки
Замечания.
Символ / (наклонная черта) может быть заменен на любой другой символ
в пределах одной команды s.
Символ / (наклонная черта) может использоваться внутри выражения
regexp, если ему предшествует знак \
. Символ конца строки
SPMlt;NL>; может использоваться внутри regexp с использованием
последовательности из двух символов
\n
(обратный слеш и n).
За командой редактирования s могут следовать (или не следовать) флаги, к обсуждению которых мы переходим.
Замечание.
Некоторые реализации sed, такие как описываемая, будут печатать все
строки вводного файла дважды, если режим auto-print не отключ©н и
использована команда p.
Другие варианты sed могут печатать каждую строку лишь однажды.
Оба способа поведения sed не являются ошибкой.
Здесь обсуждаются команды sed, которые тоже очень полезны при составлении скриптов и редактировании текстов внутри скриптов.
echo жужжал | sed y/жул/gul/
guggаl
Строки следующие за этой командой будут помещены за обрабатываемой
строкой. Все строки кроме последней должны заканчиваться знаком \
(обратный слеш). Например:
$ cat t 3 a\ Да вы переполнили \ все \ файловые системы $ df | awk '{print $5, $6}' | sed -f t Use% Mounted 12% / 33% /boot Да вы переполнили все файловые системы 85% /data03 53% /data04 74% /data05 86% /usr 56% /var 99% /data02Как видим, строки из файла t по команде a были введены после третьей строки в результирующем выводе.
Немедленно вывести строки текста, следующие за этой командой.
Все строки кроме последней должны заканчиваться знаком \
(обратный слеш). Например:
$ cat t 1 i\ Да вы переполнили \ всe файловые системы $ df | awk '{print $5, $6}' | sed -f t Да вы переполнили всеe файловые системы Use% Mounted 12% / 33% /boot 85% /data03 53% /data04 74% /data05 86% /usr 56% /var 99% /data02Как видим текст, следующий за командой i, введ©н до заданной строки. Если не задать адрес, то перед каждой строкой из вводного файла будут выводиться строки, следующие за командой i.
Удалить из вводного потока строки соответствующие интервалу заданному
адресами, а вместо них вывести строки, следующие после команды c.
Все строки кроме последней должны заканчиваться знаком \
(обратный слеш). Например:
$ cat t 1,5 c\ Это будет новый заголовок $df | awk '{print $5, $6}' | sed -f t Это будет новый заголовок 74% /data05 86% /usr 56% /var 99% /data02Как видим, строки с 1 по 5 включительно были заменены на новую строку. Посмотрим, что будет, если не использовать адресный интервал:
$ cat t c\ Это будет новый заголовок $df | awk '{print $5, $6}' | sed -f t Это будет новый заголовок Это будет новый заголовок Это будет новый заголовок Это будет новый заголовок Это будет новый заголовок Это будет новый заголовок Это будет новый заголовок Это будет новый заголовок Это будет новый заголовокЗдесь адрес не был указан, следовательно sed заменил каждую строку из вводного потока на строку, следующую после команды c.
SPMlt;NL>;.
Например,
$ df | awk '{print $6}' | sed = 1 Mounted 2 / 3 /boot 4 /data03 5 /data04 6 /data05 7 /usr 8 /var 9 /data02
$ echo "ЖужжалиБабочкиЖужжалиБабочки" | sed -n l \366\325\326\326\301\314\311\342\301\302\317\336\313\311\366\325\326\ \326\301\314\311\342\301\302\317\336\313\311$Как видим Кириллица распозна©тся как не изображаемые символы.
SPMlt;NL>; в основной буфер, затем поместить туда очередную
строку из вводного потока. Если вводной поток исчерпан, то завершить sed без обработки оставшихся команд.
SPMlt;NL>;.
SPMlt;NL>; к содержимому дополнительного буфера. Затем добавить
содержимое основного буфера к содержимому дополнительного.
SPMlt;NL>; к содержимому основного буфера. Затем добавить
содержимое дополнительного буфера к содержимому основного.
Использование команд программирования может потребоваться в специальных случаях.
Определить положение метки с именем label.
Пример простой несколько искусственной программы, которая
заменяет первый встреченный в вводном потоке знак /
(слеш) на
букву Щ и завершает работу.
$ cat t s/\//Щ/p t Mylabel b : Mylabel q $ df | awk '{print $6}' | sed -n -f t Щdev/sda6 497636 55293 416643 12% /Здесь, в соответствии с командой s. заменяется только первый встреченный слеш. Далее производится условный переход к метке с именем Mylabel и завершается выполнение sed. До тех пор пока слеш не встретился, выполнение после команды t Mylabel продолжается и интерпретируется следующая команда b, т.е. снова вводится очередная строка вводного потока и над ней производится команда
s/\//Щ/p
.
<