Команды sed

Основные команды(#,q,d,p,n,{},s).

Если вы используете 'sed', вы обязаны знать эти команды:
#

[без адреса]

Символ '#' служит для обозначения комментария. Комментарий длится от символа "#", и до конца строки. Для переносимости, самый первый символ скрипта может быть "#".

Предостережение

Если первые 2 символа комментария "#n", то их sed будет считать как опцию -n (без вывода), если вам нужен такой комментарий, используйте "# n" или "#N".

Замечание

(drBatty) Что касается самой первой строки, то я там ставлю sha-bang
#!/bin/sed -rf
после чего, я могу запускать свои скрипты, как обычные команды (./my_sed_script во время отладки, а перенеся их в /usr/local/bin/, просто набрав my_sed_script). Оболочка сама определяет, что это sed-скрипт и выполняет его. Таким скриптом можно пользоваться как и обычной sed, например:
  1. $ cat input.txt | my_sed_script > output.txt
    я вывожу в stdout входной файл(input.txt), он обрабатывается моим скриптом, и записывается в output.txt
  2. $ my_sed_script input.txt > output.txt
    тоже самое, что и в п1, просто тут сам скрипт читает файлы
  3. $ my_sed_script test.txt -i.bak
    Редактирование "на месте", отредактированный файл записывается ВМЕСТО test.txt, при этом, старый файл сохраняется под именем "test.txt.bak".
  4. $ my_sed_script *.html -ibackup_dir/*
    В данном случае, оболочка выдаёт моему скрипту все html файлы, которые скрипт последовательно обрабатывает(каждый отдельно, см. описание -i выше). При этом, старые файлы сохраняются в каталоге backu_dir(если он есть и доступен).
Что касается "#n", то лично у меня это НЕ работает. Возможно, это связано с sha-bang, а может ещё с чем-то. Конечно, лучше не ставить таких комментов. Я, для себя, взял за правило: ВСЕГДА ставить после # пробел(ну конечно кроме sha-bang)

q [EXIT-CODE]

Эта команда принимает только один адрес.

Прерывание работы скрипта. Если не запрещён автоматический вывод буфера (без опции -n), буфер выводится в выходной поток. Можно дополнительно задать код завершения (EXIT-CODE). (это GNU расширение).

d

Удаляет содержимое буфера; после чего переходит к следующему циклу.

Замечание

(drBatty): таким образом, эта команда примерно эквивалентна
{ s/.*//; b }
но при этом, ничего не выводится, все команды после d не выполняются. (потому сложно сказать, действительно-ли очищается буфер) конечно "sed '5d'" действительно отфильтрует пятую строку, но при этом, следует помнить, что не всё так просто... См. также.

p

Печать буфера (в stdout). Эту команду имеет смысл использовать только при использовании опции -n.

Замечание

в моей версии sed применение этой команды без опции -n приводит к дублированию строк, в оригинале написано, что другие версии могут печатать только один раз, а стандарт POSIX трактует это как ошибку.

Потому в переносимых скриптах НЕ СЛЕДУЕТ использовать команду p без ключа -n (это касается так-же модификатора p команды s).

Подсказка

(drBatty): что-же делать, если надо вывести строку 2 раза? ИМХО необходимо использовать опцию -n, и в случае дублирования дублировать команду p. Примитивный пример:
sed -n 'p;p'

n

Если авто-печать не отключена, печатает буфер, и затем заменяет содержимое буфера на следующую строку. Если авто-печать отключена (опция -n), то просто меняет содержимое буфера на следующую строку. Если следующей строки нет(текущая - последняя в тексте), то эта команда просто выводит содержимое буфера (если это разрешено), и работа скрипта завершается(следующие за n команды НЕ выполняются).

{ COMMANDS }

Группировка команд в блок. Вы можете использовать такие блоки, если хотите, что-бы некоторые команды выполнялись только для некоторых адресов(или диапазонов). Пример:

sed -n '3p;p'

эта команда будет просто печатать все строки, так-как 3p игнорируется для всех строк, однако, для третей строки команда 3p выполнится. (третья будет распечатана 2 раза).

sed -n '3{p;p}'

Ничего не распечатает, кроме третьей строки, которая выведется дважды.

Замечание

Вообще-то говоря, { является командой, и это нужно учитывать.

s

Команда 's' является самой востребованной в sed-скриптах, это команда замены. Точнее будет сказать, это команда поиска, и(если найдено) замены. Синтаксис команды:

s/РЕГУЛЯРНОЕ_ВЫРАЖЕНИЕ/ВЫРАЖЕНИЕ_ДЛЯ_ЗАМЕНЫ/МОДИФИКАТОРЫ

Символ '/' разделяет части команды. Его можно поменять на любой другой символ. Если в РЕГУЛЯРНОМ_ВЫРАЖЕНИИ или в ВЫРАЖЕНИИ_ДЛЯ_ЗАМЕНЫ требуется использовать символ-разделитель('/' обычно), то его следует за экранировать.

Базовая концепция 's' проста: она ищет РЕГУЛЯРНОЕ_ВЫРАЖЕНИЕ, и, если его найдёт, заменяет найденное на ВЫРАЖЕНИЕ_ДЛЯ_ЗАМЕНЫ.

ВЫРАЖЕНИЕ_ДЛЯ_ЗАМЕНЫ может содержать `\N' (где N - цифра 1...9), эта "обратная ссылка" заменяется на подвыражение (в скобках) из РЕГУЛЯРНОЕ_ВЫРАЖЕНИЕ. Выражения нумеруются слева-направо. Если ВЫРАЖЕНИЕ_ДЛЯ_ЗАМЕНЫ содержит '&', то он заменяется на всю найденную строку.

Замечание

(drBatty): аналогично '&' работает '\0'. По этой причине, в ВЫРАЖЕНИЕ_ДЛЯ_ЗАМЕНЫ (впрочем и в РЕГУЛЯРНОЕ_ВЫРАЖЕНИЕ) невозможно использовать октальные символы в Си-стиле (вроде \033). Они воспринимаются как обратные ссылки на всю строку. Для использования символов с восьмеричным кодом вы можете использовать конструкцию \oQQQ, где QQQ - восьмеричные цифры.

Перед обратными ссылками(«\N» и «&») вы можете поставить префикс, один из \L, \l, \U, \u, или \E. Впрочем, они работают для всего ВЫРАЖЕНИЯ_ДЛЯ_ЗАМЕНЫ Смысл этих префиксов:

\L
Заменяет БОЛЬШИЕ буквы на маленькие. Действует до \U или до \E
\l
Заменяет один следующий символ на мАЛЕНЬКИЙ.
\U
Заменяет все следующие символы на БОЛЬШИЕ, действует до \L или до \E.
\u
Заменяет один сл. символ на Большой
\E
Остановка замены регистров начатых префиксами \L и \U.

Пример использования префиксов.

В оригинале написано, что «\», «&», и перевод строки останавливают замену, однако, у меня эти символы не останавливают конвертацию регистра.

Замечание

Не останавливают конечно. Вопрос - конвертировать или нет решается в зависимости от флага конвертации. А этот флаг сбрасывается в 0 для каждой замены.
$ echo "ABC XYZ" | sed -r 's/\<\w+\>/\L\u&/g'
Abc Xyz
Тут произошло две замены, и для каждой флаги преобразования регистра были установлены заново - сначала для найденного «ABC», а затем для «XYZ».

Для команды s предусмотрено множество МОДИФИКАТОРОВ:

g
Производится замена всех найденных вхождений РЕГУЛЯРНОГО_ВЫРАЖЕНИЯ. (по умолчанию - только первое вхождение заменяется).
НОМЕР
Заменяется только заданное НОМЕРом найденное вхождение РЕГУЛЯРНОГО_ВЫРАЖЕНИЯ.

Замечание

Примечание: POSIX стандарт не описывает ситуацию комбинирования МОДИФИКАТОРОВg и НОМЕР, GNU версия sed обрабатывает такую комбинацию сл. образом: Игнорируются все совпадения до совпадения НОМЕР, а начиная с совпадения НОМЕР все заменяются. Думаю нужны примеры в данном случае:
$ echo 'ABCDEFGH' | sed 's/./-/'
-BCDEFGH
# по умолчанию заменяется только первое вхождение РЕГУЛЯРНОГО_ВЫРАЖЕНИЯ
$ echo 'ABCDEFGH' | sed 's/./+/g'
++++++++
# с МОДИФИКАТОРОМ g заменяются все вхождения
$ echo 'ABCDEFGH' | sed 's/./+/4'
ABC+EFGH
# с МОДИФИКАТОРОМ НОМЕР заменяется только заданное вхождение(здесь - четвёртое)
$ echo 'ABCDEFGH' | sed 's/./+/4g'
ABC+++++
# комбинация МОДИФИКАТОРОВ 'g' и 'НОМЕР'
# здесь заменились вхождения 4,5,6,7, и 8.
p
Если РЕГУЛЯРНОЕ_ВЫРАЖЕНИЕ найдено, то происходит вывод буфера в выходной поток.

Замечание

Если вы используете сразу два МОДИФИКАТОРА p и e, то от их порядка зависит результат. Например:
$ echo 'ABCDEFGH' | sed -n 's/.*/echo TEST/p'
echo TEST
# пример использования 'p' - простой вывод буфера.
$ echo 'ABCDEFGH' | sed -n 's/.*/echo TEST/e'
# МОДИФИКАТОР 'e' - команда выполняется, но её результат остаётся в буфере
# возможна её дальнейшая обработка другими командами sed. Например:
$ echo 'ABCDEFGH' | sed -n 's/.*/echo TEST/e;s/T/Q/p'
QEST
# первая команда 's' вывела в буфер слово TEST(при этом мы ничего не увидели),
# а вторая команда заменила T на Q, и вывела буфер.
$ echo 'ABCDEFGH' | sed -n 's/.*/echo TEST/ep'
TEST
# (МОДИФИКАТОР выполнить и распечатать), тут команда выполнилась, и мы видим результат
# её работы. Обычно это и нужно.
$ echo 'ABCDEFGH' | sed -n 's/.*/echo TEST/pe'
echo TEST
# (МОДИФИКАТОРЫ распечатать и выполнить) здесь сначала команда распечаталась,
# а потом выполнилась. Результат её работы сохранён в буфере, для дальнейшей обработки.
$ echo 'ABCDEFGH' | sed -n 's/.*/echo TEST/pep'
sed: -e выражение #1, символ 18: несколько модификаторов `p' с командой `s'
# а вот такое недопустимо.
# если вы хотите распечатать-выполнить-распечатать, напишите `p' отдельной командой:
$ echo 'ABCDEFGH' | sed -n 's/.*/echo TEST/pe;p'
echo TEST
TEST

Замечание

В данном примере используется неверное применение замены модификатора pep (который не поддерживается). Более правильным будет использование команды T после команды s///pe.
w FILE-NAME
выводит содержимое буфера в FILE-NAME. Расширение GNU: допустимо использовать специальные устройства /dev/stderr, и /dev/stdout.
e
Этот МОДИФИКАТОР выполняет команду из буфера. Команда выполняется как отдельный процесс, вроде вызова по конвейеру. См. примечания к МОДИФИКАТОРУ p Команда завершается символом новой строки, если она завершается «\000», то результат работы не определён. Это расширение GNU.
I, i
Этот модификатор заставляет считать БОЛЬШИЕ и малые буквы при поиске РЕГУЛЯРНОГО_ВЫРАЖЕНИЯ эквивалентными. Это расширение GNU.
M, m
Поиск РЕГУЛЯРНОГО_ВЫРАЖЕНИЯ в многострочном режиме. См. описание одноимённого модификатора адресного выражения.

Другие команды(y,a,i,c,=,l,r,w,D,N,P,h,H,g,G,x).

Многие sed-скрипты используют только команду s, описанную в прошлой секции, однако, не стоит забывать, что sed умеет намного больше простой замены. Вот список часто используемых команд sed:

y/ЗАМЕНЯЕМЫЕ_СИМВОЛЫ/ЗАМЕНЯЮЩИЕ_СИМВОЛЫ/

(в этой команде, при необходимости, разделитель «/» можно заменить на любой другой символ)

Эта команда заменяет символы из списка ЗАМЕНЯЕМЫЕ_СИМВОЛЫ, на символы из списка ЗАМЕНЯЮЩИЕ_СИМВОЛЫ. Списки должны быть одинаковой длинны (после де-экранирования).

Замечание

(drBatty): В отличие от perl'а и прочих языков, тут нельзя задавать диапазоны и всякие другие извраты. Всё должно быть предельно ясно:
y/ABC/XYZ/
эта команда меняет «A» на «X», «B» на «Y», и «C» на «Z». Другие форматы не допускаются. Потому на sed невозможно написать классический "однострок на перле". Не думаю, что это большой минус. Хотя иногда приходится много кнопок давить :-(

Внимание

Ну и как обычно, я впишу красненький «warning». Сама sed конечно не сможет исполнить «однострок на перле», однако, вы всё-же будьте внимательны...

Глюки и баги могут возникнуть и сами по себе, к примеру так.

a TEXT

В режиме «POSIXLY_CORRECT», эта команда имеет один адрес. В конце текущего цикла, в выходной поток добавляется TEXT. Как расширение GNU, можно писать:

$ echo 'ABCDEFGH' | sed -n 'a text1\
text2\
text3\
text4'
text1
text2
text3
text4

как видите, символы «\» удаляются (как и в языке Си).

Это расширение так-же работает и в командах i и c.

i TEXT
Так-же как a, но TEXT выводится перед выводом буфера.
c TEXT
Так-же как a, но TEXT выводится вместо выводам буфера.
=
Так-же как i, но выводится не заданный текст, а номер текущей строки. Пример:
$ echo 'ABCDEFGH' | sed  'a TEST'
ABCDEFGH
TEST
$ echo 'ABCDEFGH' | sed  'i TEST'
TEST
ABCDEFGH
$ echo 'ABCDEFGH' | sed  'c TEST'
TEST
$ echo 'ABCDEFGH' | sed  '='
1
ABCDEFGH
l [N]

Вывод буфера в переносимой форме: непечатные символы(а так-же «\») выводится в Си-стиле (тремя восьмеричными цифрами, и перед ними добавляется «\») Длинные строки разрезаются, при резке в конец новых строк добавляется «\», Конец каждой строки помечается символом «$».

N определяет максимальный размер строки, если не задан, принимается значение заданное в командной строке ключом -l, если и он не задан, N=70. Если N=0, строки не разбиваются. Параметр N - расширение GNU.

r FILENAME

Эта команда читает файл FILENAME в конце текущего цикла (или перед чтение следующей строки), и выводит его содержимое в выходной поток. Если файл не удалось прочитать, или файл пустой, то ничего не происходит, и никаких сообщений об ошибке НЕ выводится. Пример:

$ cat z
aaaaa
# содержимое файла z
$ echo 'ABCDEFGH' | sed  'r z
s/./X/'
XBCDEFGH
aaaaa
# сначала стоит команда r, а затем команда s,
# однако мы видим, что sed выполняет команды не так, как мы их записали,
# а в соответствии с этим документом:
# СНАЧАЛА выполняется команда s, которая заменяет символ в буфере,
# затем содержимое буфера выводится,
# и лишь ПОСЛЕ этого, выполняется чтение и вывод файла (не думаю, что чтение
# осуществляется ДО этого, в какую-то временную память).

В режиме «POSIXLY_CORRECT», эта команда имеет только один адрес.

w FILENAME

Записывает буфер в FILENAME. См. так-же описание модификатора w команды s.

Эта команда сначала создаёт файл (или, если уже есть, усекает его до нулевой длинны), а потому уже записывает. Если файл открыть не получилось, эта команда пытается его закрыть, и снова открыть. Если файл так и не открылся для записи, работа прерывается с сообщением об ошибке. Это так-же касается модификатора w команды s.

D

Это совсем мутная команда, здесь кардинальным образом нарушается вся работа sed:

  1. читаем строку из входного файла в буфер.
  2. выполняем скрипт до команды D.
  3. Выполняем команду D:
    1. Первым делом удаляем из буфера все символы до первого «\n». Т.е. всю строку, если в буфере 1 строка, и только первую, если строк много.
    2. если в буфере пусто, то переходим к п1.
    3. если в буфере НЕ пусто, то переходим к п2.
  4. Никакие команды после D, а так-же никакая печать буфера после D НЕ выполняется.

Таким образом, можно напихать в буфер множество строк, а после этого все это строки обработать по одной. Весь скрипт получается таким своеобразным циклом, который не слишком и удобен, по той причине, что точка входа в цикл всего одна, и совпадает с началом скрипта. Конечно, хотя точка входа единственная, точек выхода сколько угодно, и конечно эту команду всегда можно обойти.

Пример.

Замечание

Работа команды D оптимизирована - она вовсе не удаляет символы - она смещает указатель на начало строки за первый встреченный символ «\n». По этой причине команда D часто работает намного быстрее, чем эквивалентная замена, вроде этой:
s/^[^\n]*\n//
См. также.

N

Добавляет новую строку из входного потока к буферу. Строки разделяются символом новой строки(\n). Если нет следующей строки, то работа sed завершается без выполнения оставшихся команд. Команда довольно мутная, поясню примером с прошлым файлом из двух строк:

$ sed 'N' 2l.txt
line 1
second line
# никаких изменений, файл никак не поменялся,
# но это только с виду.
# на самом деле, выполнился только один цикл работы sed,
# сначала загрузилась первая строка (как обычно), а затем - вторая,
# командой N, затем содержимое буфера вывелось на экран.
# но так-как строки разделены \n, это выглядит как и оригинальный вывод (например
# командой cat)
$ sed 'N;s/\n/WWW/' 2l.txt
line 1WWWsecond line
# можно заменить \n в буфере на что-то другое, и тогда станет видно, что в
# действительности это просто одна строка, хотя и с символом \n в середине.

Пример.

P

Печать буфера сначала, и до первого символа \n.

Пример.

h

Запись буфера в буфер2 (hold space).

H

Добавление буфера к буферу2. Например:

буфер: АБВ
буфер2: ГДЕ
после команды H:
буфер: АБВ
буфер2: ГДЕ\nАБВ

g

Замена содержимого буфера, на содержимое буфера2.

G

Добавляет к буферу содержимое буфера2. (вроде H, только меняется буфер).

x
Обмен содержимым буфера и буфера2

Замечание

Ещё одно примечание: для работы с буфером2 (областью удержания) есть довольно много команд, если вам нужно просто копирование - предпочтительнее использовать x, она в некоторых случаях должна работать быстрее (а фиг там! В текущей версии sed(4.2) это не так, см здесь), иначе используйте g и h. Команды G и H отличаются результатом: например если в буфере будет "АБВ", а в буфере2 будет "ГДЕ", и мы выполним G, то результат в буфере будет "АБВ\nГДЕ", а вот если мы выполним команду H, то не только результат поместится в область удержания, но и поменяется, получится "ГДЕ\nАБВ".

Команды для sed гуру(:,b,t).

Во многих случаях, используя следующие команды, вы можете избежать кодинга на других языках (вроде perl & awk), и решить задачи средствами самой sed.

Замечание

ага. Чтоб мну не обвиняли в подтасовке фактов процитирую оригинал:
In most cases, use of these commands indicates that you are probably better off programming in something like `awk' or Perl. But occasionally one is committed to sticking with `sed', and these commands can enable one to write quite convoluted scripts.

: LABEL
Безадресная команда. Она задаёт метку, для перехода командами t, T, и b.
b [LABEL]
Безусловный переход на метку LABEL. Если LABEL не применяется, то завершает этот цикл, и начинает следующий.
t [LABEL]
Переход по метке LABEL. В том случае, если последняя команда s успешно завершилась (произвела замену). При этом, если LABEL опущена, команда прерывает цикл, и начинает следующий. Если прошлая команда s не произвела замены, команда ничего не делает.

Подсказка

условный переход в sed вовсе не обязательно делать с помощью `t'! Вы можете с лёгкостью использовать команду `b' с адресом. Например переход на lable в команде
/X/ b lable
осуществляется тогда, и только тогда, когда в буфере есть хотя-бы одна буква X. Многоуровневые, вложенные и обратные (в т.ч. циклы) переходы тоже работают.

Предостережение

Команду t так-же частенько глючит, если есть 2 команды s, причём первая выполняется всегда, а вторая - иногда, и после второй стоит команда t, то переход будет выполнен в любом случае. Думаю, что это какой-то древний и очень старый баг. Для исправления ситуации, поставьте после первой s ещё одну команду t передающую управление на вторую s. Проблема в том, что если этот баг исправить, то множество скриптов перестанут правильно работать, а так-как эти команды юзают только гуру вроде нас, то разработчикам можно и не фиксить данный баг - наши скрипты и дальше будут работать правильно, я вас предупредил, и вы теперь в курсе. Что до ламеров, которые не читают ни доки, ни чужой код - ССЗБ.

Замечание

Поковыряв исходники, я выяснил, что команда s только устанавливает флаг перехода (и то не всегда, а только тогда, когда произошла замена), но команда s никогда не сбрасывает флаг перехода. Он сбрасывается только командами t и T. Кроме того, флаг перехода сбрасывается во время загрузки строки в буфер в начале цикла работы sed. Если вы загружаете строки командами n и/или N, то флаг перехода не сбрасывается. Потому и приходится применять такой код:
# здесь какие-то sed команды, в том числе и команды замены
# которые иногда заменяют, а иногда - нет.
t label # переход к метке label, нет разницы, выполнится он или нет
:label # потому-что метка label стоит сразу после команды перехода.
s/ABC/&/
t found # преход выполнится только если будет найдено 'ABC'

Замечание

Что-же значит «ССЗБ»? Сам Себе Злобный Буратино

Команды специфичные для GNU `sed'(e,L,Q,R,T,v,W)

Эти команды специфичны для GNU версии sed, вы можете использовать их в том, и только в том случае, если вы уверены, что ваши скрипты не понадобится запускать на других версиях sed.

Замечание

(drBatty): Наверное имеется ввиду версия sed от NecroSoft, которая не поддерживает половину команд, и стОит всего $49.50 :-)

e [COMMAND]
Эта команда вызывает по конвейеру (pipe) оболочку sh, которая выполняет команду COMMAND. Если COMMAND отсутствует, выполняется команды из входного потока. (см. так-же команду s, модификатор e).
L N
Это расширение разбивает длинную строку на короткие. Строка разделяется по пробельным символам. Насколько строка "длинная" определяется параметром N (либо ключом -l, если N отсутствует). Работает примерно как команда fmt. См. так-же описание команды l.
Q [EXIT-CODE]
Эта команда может иметь только один адрес. Работает так-же как q, но не выводит содержимое буфера в конце цикла. В оригинале написано, что эта команда представляет собой альтернативный путь, что-бы не использовать ключ -n в тривиальных функциях.
R FILENAME
Так-же как r, но читается только одна строка из файла FILENAME. Например:
$ sed 'R file1' file2
выведет сначала первую строку файла2, потом первую строку файла1, затем вторую файла2 и т.д. Т.о. эта команда выведет оба файла, второй в нечётных, а первый в чётных строках результата.
T [LABEL]
так-же как t, но переход выполняется в случае неудачной замены команды s.
v VERSION
Эта команда ничего не делает, если версия sed моложе или такая-же как VERSION. В противном случае скрипт прерывается с ошибкой.
$ sed -version
GNU sed version 4.0.9
Copyright (C) 2003 Free Software Foundation, Inc.
Эта программа - свободное программное обеспечение; условия её копирования
смотрите в исходных текстах. Не предоставляется НИКАКИХ гарантий; даже
подразумеваемых гарантий ПОЛЕЗНОСТИ или ПРИГОДНОСТИ ДЛЯ КОНКРЕТНОЙ ЦЕЛИ,
в той мере, в которой это может быть допущено законодательством.
$ sed 'v 4.0'
$ sed 'v 4.1'
sed: -e выражение #1, символ 5: expected newer version of sed
Вот более современная версия:
$ sed -version
GNU sed версия 4.2
Copyright (C) 2003 Free Software Foundation, Inc.
Это свободное программное обеспечение; условия его копирования смотрите в
исходных текстах. Не предоставляется НИКАКОЙ гарантии; даже гарантии
ПРИГОДНОСТИ ДЛЯ ПРОДАЖИ или ПРИМЕНИМОСТИ ДЛЯ КОНКРЕТНОЙ ЦЕЛИ, в той мере,
в которой это может быть допущено законодательством.

GNU sed home page: <http://www.gnu.org/software/sed/>.
General help using GNU software: <http://www.gnu.org/gethelp/>.
Отчеты об ошибках отправляйте по адресу: <bug-gnu-utils@gnu.org>.
Убедитесь, что включили где-либо в поле ``Тема:'' слово ``sed''.
$ sed 'v 4.2'
^C
$ sed 'v 4.3'
sed: -e выражение #1, символ 5: ожидалась более новая версия sed

Подсказка

Эту команду можно использовать в том случае, если мы не уверены в версии sed у пользователя. К примеру, если мы решили применить команду z. Если версия sed слишком старая, то юзер получит сообщение об ошибке, в котором сказано, что ему следует использовать более новую версию sed.
W FILENAME
Так-же как w, но пишется не всё содержимое буфера, а только до первого «\n». Кроме того, после записи файл не закрывается, и в следующих циклах в него можно дописать подстроки из буфера. Например:
sed 'W file2' file1
Скопирует построчно файл1 в файл2.

Подсказка

Конечно file1 можно как-нибудь отредактировать этой командой в процессе записи. Разница между командами w и W следующая: первая выводит буфер в файл, и закрывает последний, а вторая не закрывает - файл закрывается только после обработки всего входного потока.

Команда z

Замечание

(drBatty): В новейших версиях GNU sed появилась новая команда z, она очищает буфер. Однако, пока ещё в большинстве систем эта версия не установлена, и очищать приходится командой s/.*//, что во первых не работает если в буфере есть НЕСИМВОЛЫ, и во вторых теряется флаг для команд перехода.

Подробнее про эту команду см. здесь. И здесь.

Вы можете обсудить этот документ на форуме. Текст предоставляется по лицензии GNU Free Documentation License (Перевод лицензии GFDL).

Вы можете пожертвовать небольшую сумму яндекс-денег на счёт 41001666004238 для оплаты хостинга, интернета, и прочего. Это конечно добровольно, однако это намного улучшит данный документ (у меня будет больше времени для его улучшения). На самом деле, проект часто находится на грани закрытия, ибо никаких денег никогда не приносил, и приносить не будет. Вы можете мне помочь. Спасибо.