HANDY ONE-LINERS FOR SED (Unix stream editor) 23 марта, 2001
ШПАРГАЛКА ПО SED
собранные Эриком Пементом (Eric Pement) <[email protected]> версия 5.1
Последняя версия доступна на:
www.student.northpark.edu/pemente/sed/sed1line.txt
www.cornerstonemag.com/sed/sed1line.txt
This file is also available in Portuguese at:
www.lrv.ufsc.br/wmaker/sed_ptBR.html
Теперь и по-русски:
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)/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’ «$@" | 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 # по-другому, но работает шустрее
Добавить комментарий