HANDY ONE-LINERS FOR SED (Unix stream editor) 23 марта, 2001 ШПАРГАЛКА ПО SED собранные Эриком Пементом (Eric Pement) <pemente@northpark.edu> версия 5.1 Последняя версия доступна на: http://www.student.northpark.edu/pemente/sed/sed1line.txt http://www.cornerstonemag.com/sed/sed1line.txt This file is also available in Portuguese at: http://www.lrv.ufsc.br/wmaker/sed_ptBR.html Теперь и по-русски: http://rkorepanov.narod.ru/doc/sed.html РАЗРЫВЫ ФЙЛА: # заменяем ПРОБЕЛ на двойной пробел 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\)/\1bar\2/' # заменяет друг за другом 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\)/&\2\1/;//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\}\)/\1\2,\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; /^\(.*\)\n\1$/!P; D' # удалить дублирующиеся непоследовательные строки файла. Острожнее с # переполнением размера буфера, занятой памяти, лучше используйте GNU sed! sed -n 'G; s/\n/&&/; /^\([ -~]*\n\).*\n\1/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' "$@" | 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; http://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 # по-другому, но работает шустрее Если у вас есть еще скрипты для распространения или если вы нашли ошибки в этой листовке, плиз пошлите мыло автору листовки. Напишите какую версию sed вы юзаете, ось, под которою скомпилен тот самый сед, и описание проблемы. Данные скрипты в этом файле были написаны и распространяются господами: Al Aab <af137@freenet.toronto.on.ca> # модератор "sedеров" Edgar Allen <era@sky.net> # разное Yiorgos Adamopoulos <adamo@softlab.ece.ntua.gr> Dale Dougherty <dale@songline.com> # автор "sed & awk" Carlos Duarte <cdua@algos.inesc.pt> # автор "do it with sed" Eric Pement <pemente@northpark.edu> # автор этого перевода Ken Pizzini <ken@halcyon.com> # автор GNU sed v3.02 S.G. Ravenhall <stew.ravenhall@totalise.co.uk> # скрипт для de-html Greg Ubben <gsu@romulus.ncsc.mil> # приложения и помощь
------------------------------------------- Korepanov Roman <rk1@chat.ru> # перевод на русский язык