ШПАРГАЛКА ПО SED

РАЗРЫВЫ ФЙЛА:

# заменяем ПРОБЕЛ на двойной пробел
sed G

# ставим двойной пробел с уже имеющимися в файле пустыми строками. Выходной файл
# должен содержать не более одной пустой строки между строками текста
sed '/^$/d;G'

# Тройной пробел в файле
sed 'G;G'

# отменить двойные пробелы (предполагается, что пронумерованные строки всегда пустые)
sed 'n;d'

ЧИСЛА:

# ставим номер каждой строки файла (левое выравнивание). Использование табуляции (смотри
# особенности применения 't' в конце этого файла) в отличие от пробела сохранит отступ(ы).
sed = filename | sed 'N;s/n/t/'

# ставим номер каждой строки файла (число слева, выравненное по правому краю)
sed = filename | sed 'N; s/^/ /; s/ *(.{6,})n/1 /'

# ставим номер каждой строки файла,но только если строка не пустая
sed '/./=' filename | sed '/./N; s/n/ /'

# считаем количество строк (аналог "wc -l")
sed -n '$='

ПРЕОБРАЗОВАНИЯ И ЗАМЕНА ТЕКСТА:

# В СРЕДЕ UNIX: переводит DOS стандарт перевода строки (CR/LF) в формат Unix
sed 's/.$//' # полагем , что все строки оканчиваются CR/LF
sed 's/^M$//' # в bash/tcsh, нажимем Ctrl-V затем Ctrl-M
sed 's/x0D$//' # для gsed 3.02.80, но выше попроще

# В СРЕДЕ UNIX: преобразовываем символы новой строки Unix (LF) в DOS формат
sed "s/$/`echo -e \r`/" # командная строка в ksh
sed 's/$'"/`echo \r`/" # командная строка в bash
sed "s/$/`echo \r`/" # командная строка в zsh
sed 's/$/r/' # для gsed 3.02.80

# В СРЕДЕ ДОС: преобразуем символы перевода строк Unix (LF) в DOS формат
sed "s/$//" # способ 1
sed -n p # способ 2

# В СРЕДЕ ДОС: преобразуем символы перевода строки ДОС (CR/LF) формат Unix
# этого нельзя сделать DOS версией sed. Используем "tr"
tr -d r <infile >outfile # GNU tr версии 1.22 или выше

# удаляем отступы (пробелы,табуляции) с начала каждой строки
# выравниваем текст полностью по левому краю
sed 's/^[ t]*//' # смотри проблемы с 't' в конце файла

# удалить замыкающие пробелы, табуляции с конца каждой строки
sed 's/[ t]*$//' # смотри проблемы с 't' в конце файла

# удаляем отступы, пробелы, табуляции и с конца , и с начала строки
sed 's/^[ t]*//;s/[ t]*$//'

# вставляем 5 пробелов в начале каждой строки (отступ для строки)
sed 's/^/ /'

# выравниваем весь текст справа по ширине колонки 79 символов
sed -e :a -e 's/^.{1,78}$/ &/;ta' # 78 плюс 1 пробел

# центрируем весь текст посредине при ширине колонки 79 символов.В первом способе
# пробелы в начале строки нужны, а пробелы в конце строки дополняются до конца строки.
# Второй способ, пробелы в начале строки отбрасываются в центр строки, и нет
# завершающих пробелов до конца строки.
sed -e :a -e 's/^.{1,77}$/ & /;ta' # Способ 1
sed -e :a -e 's/^.{1,77}$/ &/;ta' -e 's/( *)1/1/' # Способ 2

# подстановка (найти и заменить) "foo" на "bar" в каждой строке
sed 's/foo/bar/' # заменяет только первое вхождение в строке
sed 's/foo/bar/4' # заменяет только 4 вхождение в строке
sed 's/foo/bar/g' # заменяет ВСЕ вхождения в строке
sed 's/(.*)foo(.*foo)/1bar2/' # заменяет друг за другом
sed 's/(.*)foo/1bar/' # заменяет только завершающее слово

# ЗАМЕНЯЕТ "foo" на "bar" ТОЛЬКО для строк ,содержащих "baz"
sed '/baz/s/foo/bar/g'

# подставляет "foo" на "bar" КРОМЕ строк, содержащих "baz"
sed '/baz/!s/foo/bar/g'

# меняет "scarlet" или "ruby" или "puce" на "red"
sed 's/scarlet/red/g;s/ruby/red/g;s/puce/red/g' # большинство sedов
gsed 's/scarlet|ruby|puce/red/g' # только GNU sed

# обратный порядок строк (эмулирует "tac")
# баг/фича в HHsed v1.5 - пустые строки удаляются
sed '1!G;h;$!d' # способ 1
sed -n '1!G;h;$p' # способ 2

# обратный порядок символов в строке (походит на "rev")
sed '/n/!G;s/(.)(.*n)/&21/;//D;s/.//'

# соединяет строки друг с дружкой (как "paste")
sed '$!N;s/n/ /'

# если строка оканчивается обратным слэшем, добавляем последующую строку к ней
sed -e :a -e '/\$/N; s/\n//; ta'

# если строка начинается с знака равно , добавляем ее к предыдущей строке
# и заменяем "=" на один пробел
sed -e :a -e '$!N;s/n=/ /;ta' -e 'P;D'

# добавляем запятые к числовым строкам, меняя "1234567" на "1,234,567"
gsed ':a;s/B[0-9]{3}>/,&/;ta' # GNU sed
sed -e :a -e 's/(.*[0-9])([0-9]{3})/1,2/;ta' # остальные sed

# добавляем запятые к числам с десятичной точкой и знаком минуса (GNU sed)
gsed ':a;s/(^|[^0-9.])([0-9]+)([0-9]{3})/12,3/g;ta'

# добавляем пустую строку каждые пять 5 строк (после строк 5, 10, 15, 20, итд.)
gsed '0~5G' # только GNU sed
sed 'n;n;n;n;G;' # другие sedы

ВЫБОРОЧНАЯ ПЕЧАТЬ ОПРЕДЕЛЕННЫХ СТРОК:

# печать первых 10 строк файла ( поведение "head")
sed 10q

# печать первой строки файла (поведение "head -1")
sed q

# печать последних 10 строк файла ( "tail")
sed -e :a -e '$q;N;11,$D;ba'

# печать последних 2 строк файла ( "tail -2")
sed '$!N;$!D'

# печать последней строки файла ( "tail -1")
sed '$!d' # способ 1
sed -n '$p' # способ 2

# печать только строк ,которые совпадают с regexp ( "grep")
sed -n '/regexp/p' # способ 1
sed '/regexp/!d' # способ 2

# печать только строк , НЕ совпадающих с regexp (как "grep -v")
sed -n '/regexp/!p' # способ 1, соответствует вышеприведенному
sed '/regexp/d' # спопоб 2, простейший синтаксис

# печать строки непосредственно перед regexp, но не строки
# содержащей regexp
sed -n '/regexp/{g;1!p;};h'

# печать строки непосредственно после regexp, но не строки
# содержащей regexp
sed -n '/regexp/{n;p;}'

# печать 1 строки контекста перед и после regexp,с номером строки,
# показывающей , сколько regexp встретилось (как в "grep -A1 -B1")
sed -n -e '/regexp/{=;x;1!p;g;$!N;p;D;}' -e h

# grep для AAA и BBB и CCC (в любом порядке)
sed '/AAA/!d; /BBB/!d; /CCC/!d'

# grep для AAA и BBB и CCC (в таком же порядке)
sed '/AAA.*BBB.*CCC/!d'

# grep для AAA или BBB или CCC (как в "egrep")
sed -e '/AAA/b' -e '/BBB/b' -e '/CCC/b' -e d # большинство sedов
gsed '/AAA|BBB|CCC/!d' # только для GNU sed

# печать параграфа если тот содержит AAA (пустые строки,разделенные параграфами)
# HHsed v1.5 должен содержать 'G;' после 'x;' в следующих 3 скриптах
sed -e '/./{H;$!d;}' -e 'x;/AAA/!d;'

# печать параграфа если тот содержит AAA и BBB и CCC (в любом порядке)
sed -e '/./{H;$!d;}' -e 'x;/AAA/!d;/BBB/!d;/CCC/!d'

# печать параграфа если тот содержит AAA или BBB или CCC
sed -e '/./{H;$!d;}' -e 'x;/AAA/b' -e '/BBB/b' -e '/CCC/b' -e d
gsed '/./{H;$!d;};x;/AAA|BBB|CCC/b;d' # только для GNU sed

# печать строк длинее 65 символов
sed -n '/^.{65}/p'

# печать строк короче 65 символов
sed -n '/^.{65}/!p' # способ 1, соответствует вышеприведенному
sed '/^.{65}/d' # способ 2, простой синтаксис

# печать секции файла от регулярного выражения до конца файла
sed -n '/regexp/,$p'

# печать секции файла , основанная на номерах строк (включающей строки 8-12 )
sed -n '8,12p' # способ 1
sed '8,12!d' # способ 2

# печать строки 52
sed -n '52p' # способ 1
sed '52!d' # способ 2
sed '52q;d' # способ 3, эффективно для больших файлов

# начиная со строки 3, печать каждой 7-ой строки
gsed -n '3~7p' # для GNU sed
sed -n '3,${p;n;n;n;n;n;n;}' # для других

# печать части файла между двумя регулярными выражениями
sed -n '/Iowa/,/Montana/p' # чувствительно к регистру

ИЗБРАННОЕ УДАЛЕНИЕ ОПРЕДЕЛЕННЫХ СТРОК:

# печать всего файла , КРОМЕ части между двумя регулярными выражениями
sed '/Iowa/,/Montana/d'

# удаление двойных,последовательных строк файла (типа "uniq").
# первая строка из дубирующихся строк сохраняется, остальные убираются
sed '$!N; /^(.*)n1$/!P; D'

# удалить дублирующиеся непоследовательные строки файла. Острожнее с
# переполнением размера буфера, занятой памяти, лучше используйте GNU sed!
sed -n 'G; s/n/&&/; /^([ -~]*n).*n1/d; s/n//; h; P'

# удаление первых 10 строк файла
sed '1,10d'

# удалить последнюю строку файла
sed '$d'

# удалить последние 2 строки файла
sed 'N;$!P;$!D;$d'

# удалить последние 10 строк файла
sed -e :a -e '$d;N;2,10ba' -e 'P;D' # способ 1
sed -n -e :a -e '1,10!{P;N;D;};N;ba' # способ 2

# удалить каждую 8 строку
gsed '0~8d' # только GNU sed
sed 'n;n;n;n;n;n;n;d;' # другие sedы

# удалить все пустые строки файла (также как и "grep '.' ")
sed '/^$/d' # способ 1
sed '/./!d' # способ 2

# удалить все ПОСЛЕДОВАТЕЛЬНЫЕ строки файла , кроме первых; также
# удаляет все пустые строки с начала и до конца файла (походит на "cat -s")
sed '/./,/^$/!d' # способ 1, разрешает 0 пустых в начале, 1 от EOF
sed '/^$/N;/n$/D' # способ 2, разрешает 1 пустых в начале, 0 от EOF

# удалить все ПОСЛЕДОВАТЕЛЬНЫЕ пустые строки из файла кроме первых двух:
sed '/^$/N;/n$/N;//D'

# удалить все пустые строки с начала файла:
sed '/./,$!d'

# удалить все завершающие файл пустые строки
sed -e :a -e '/^n*$/{$d;N;ba' -e '}' # рaботает на всех sed
sed -e :a -e '/^n*$/N;/n$/ba' # также, кроме gsed 3.02*

# удалить последнюю строку каждого параграфа
sed -n '/^$/{p;h;};/./{x;/./p;}'

СПЕЦИАЛЬНЫЕ ПРИМЕНЕНИЯ:

# удалим спецсимволы (overstrikes) (символ, бэкспейс) из man pages. Команда 'echo'
# может понадобится для ключа -e если у вас ось Unix System V или bash shell.
sed "s/.`echo \b`//g" # двойные кавычки для среды Unix
sed 's/.^H//g' # в bash/tcsh, жмите Ctrl-V затем Ctrl-H
sed 's/.x08//g' # hex (16-ричное) выражение для sed v1.5

# получаем заголовок сообщения формата Usenet/e-mail
sed '/^$/q' # удаляем все после первой пустой строки

# получить тело сообщения формата Usenet/e-mail
sed '1,/^$/d' # удаляем все до первой пустой строки

# получить заголовок темы письма , но без слова "Subject: "
sed '/^Subject: */!d; s///;q'

# получить начальный заголовок письма отправителя
sed '/^Reply-To:/q; /^From:/h; /./d;g;q'

# разобрать свойства адреса, выкинуть нафиг e-mail адрес
# с 1-строчного адресного заголовка (смотрите выше)
sed 's/ *(.*)//; s/>.*//; s/.*[:<] *//'

# добавить начальный уголок и пробел в каждую строку (квотинг сообщения)
sed 's/^/> /'

# удалить начальный уголок и пробел из каждой строки (антиквотинг сообщения)
sed 's/^> //'

# удалить теги HTML (включая многострочные теги)
sed -e :a -e 's/<[^>]*>//g;/</N;//ba'

# распаковать многотомные заююкоженые бинарники,удалить дополнительный заголовок
# и инфу, которые остаются от ююкоженой части. Файлы переданные в
# sed долны идти в правильном порядке. Версия 1 может вводиться в командной строке
# ; версия 2 может запихиваются в запускаемые скрипты Unix shell
# (Изменение от скрипта Рауля Деси (Rahul Dhesi)
sed '/^end/,/^begin/d' file1 file2 ... fileX | uudecode # Версия 1
sed '/^end/,/^begin/d' "$@&quot; | uudecode # Версия 2

# заZIPовать каждый .TXT файл отдельно,удаляя исходный и
# называя каждый .ZIP файл именем запакованного .TXT файла
# (под DOS: команда "dir /b" возвращает чисто имена файлов списком).
echo @echo off >zipup.bat
dir /b *.txt | sed "s/^(.*).TXT/pkzip -mo 1 1.TXT/" >>zipup.bat

ТИПОВОЕ ПОЛЬЗОВАНИЕ: Sed получает одну или больше команд по порядку

и применяет их при каждой операции ввода. После этого все команды применяются
к первой строке ввода,затем первая строка выводится и вторая строка ожидает
ввода для обработки , а затем цикл повторяется. Предыдущие примеры предполагают
что ввод производится со стандартного <STDIN> ,например с консоли
обычно это будет ввод трубы, вернее, канала (или контейнера) ;) (piped input). Один из
больших имен файлов добавляется в командную строку если нет ввода со
стандартного устройства ввода <STDIN>, посылаемого на устройство вывода (Экран).
Вот примерчики:

cat filename | sed '10q' # Используются каналы-контейнера
sed '10q' filename # такой же эффект но без кота ;) ("cat")
sed '10q' filename > newfile # перенаправим вывод на диск

Для дополнительных примеров , включая применение команд для ввода
команд с файла на диске , а не только в командной строке, прочитайте "sed &
awk, 2я редакция," от Даля Дугерти( Dale Dougherty) и Арнольда Руббенса
( Arnold Robbins) (O'Reilly,1997; www.ora.com), "Обработка текста в UNIX ,"
Даля Дугерти( Dale Dougherty) и Тима Орэйли (Tim O'Reilly) (Hayden Books, 1987)
или учебники от Майка Арста (Mike Arst) в файле U-SEDIT2.ZIP (нуно поискать).
Чтоб впитать силу sed, нужно понять что такое "Регулярные выражения." Для этого,
прочитайте "Регулярные выражения" от Джефри Фриддла (Jeffrey Friedl)
(O'Reilly, 1997).Читайте ("man") маны , может помочь в Unix ("man
sed", "man regexp", или подсекцию , посвященную регулярным выражениям в "man
ed"), но маны достаточно сложны. Они написаны не для обучения
sed или использованию regexp для чайников, но как как справочник
для использующих программы на практике.

ИСПОЛЬЗОВАНЕ КАВЫЧЕК: Представленные примеры используют одинарные кавычки ('...')
в отличие от двойных ("...") для ограничения редактируемых команд еще
во времена использования ed на Unix. Одинарные кавычки предохраняют
оболочку Unix от интерпретации знака бакса ($) и обратнокавычек
(`...`),которые использует шелл , если они окружены двойными кавычками.
Пользователям "csh" и аналогам также нужно экранировать
знак восклицания (!) бэкслэшем (например, !) для правильной работы
вышепредставленных примеров,даже внутри одинарных кавычек.
Версии sed для DOS всегда требуют двойные кавычки ("...") а не одинарные
для ограничения редактируемых комманд.

ИСПОЛЬЗОВАНИЕ 't' В СКРИПТАХ SED: Для чистоты документации мы использовали
выражение 't' для вывода символа табуляции (0x09) в скриптах.
Однако, меногие версии sed не распознают 't' , и для этого,когда вы пишете
эти скрипты в командной строке ,жмите вместо этого кнопочку
TAB. 't' поддеривается регулярными выражениями в awk, perl, и HHsed, sedmod,
и GNU sed v3.02.80.

ВЕРСИИ SED: Версии sed различны, поэтому возможны некотрые различия синтаксиса.
В особых случаях, может не быть поддержки меток (:name) или ветвящихся конструкций
(b,t) в пределах редактируемых команд, кроме окончания этих команд.
Мы использовали синтаксис который будет использоваться для большинства
версий sed , тогда как популярные версии сед под лицензией
GNU разрешают более последовательный синтаксис. Когда читатель видит
длиннющую команду как эта:

sed -e '/AAA/b' -e '/BBB/b' -e '/CCC/b' -e d

то хорошо бы знать, что версии GNU sed позволяют переписать это:

sed '/AAA/b;/BBB/b;/CCC/b;d' # или иначе
sed '/AAA|BBB|CCC/b;d'

В дополнение, запомните что многие версии sed понимают команды
как "/one/ s/RE1/RE2/", и НЕ разрешают "/one/! s/RE1/RE2/", в которых
содержится пробел перед 's'. Остерегайтесь пробелов при вводе команд.

ОПТИМИЗАЦИЯ СКОРОСТИ: Если скорость выполнения хочется увеличить (для
больших входных файлов или слабоватого "железа", замена будет
работатать быстрее с выражением поиска находящимся перед
инструкцией вида "s/.../.../" Например:

sed 's/foo/bar/g' filename # стандартная команда замены
sed '/foo/ s/foo/bar/g' filename # это работает быстрее
sed '/foo/ s//bar/g' filename # укороченый синтаксис sed

В строке выборки или удаления, которая используется вами для вывода строк
выбранной части файла, команда выхода (q) в скрипте намного уменьшает время
обработки для больших файлов. Вот пример:

sed -n '45,50p' filename # печать строки 45-50 позиции файла
sed -n '51q;45,50p' filename # по-другому, но работает шустрее