sed – это stream editor. Часто используется в скриптах для различных преобразований текста. Очень мощный инструмент, если понять как он работает. Ниже приведено несколько типичных примеров.
- Удаление из файла заданных строк.
Пусть, например, нужно удалить строки из файла, в которых содержится подстрока «phone: xxx-xx-xx» (вместо символа x — цифры):-
sed "/phone: [0-9]\{3\}-[0-9]\{2\}-[0-9]\{2\}/ d" test.txt
Здесь между слешами (/) задается шаблон (регулярное выражение), после него стоит оператор «d» (от слова delete), который удаляет строки файла test.txt, совпадающие с шаблоном. Результат:
-
$ cat test.txt
-
phone: 111-22-44
-
phone: 111-22-45
-
phone: 311-22-d4
-
phone: 111-22-55
-
-
$ sed "/phone: [0-9]\{3\}-[0-9]\{2\}-[0-9]\{2\}/ d" test.txt
-
phone: 311-22-d4
Для противоположного эффекта (если хотим удалить из файла строки, НЕ попадаюащие под шаблон) нужно добавить восклицательный знак после закрывающего регулярное выражение слеша:
-
$ sed "/phone: [0-9]\{3\}-[0-9]\{2\}-[0-9]\{2\}/! d" test.txt
-
phone: 111-22-44
-
phone: 111-22-45
-
phone: 111-22-55
Если нужно, чтобы изменения происходили сразу в файле, без вывода в stdout, нужно добавить ключ --in-place (-i).
-
- Добавление в файл строки в определённом месте.
Вставляем мета-тег с указанием кодировки документа перед закрывающим тегом </head> во все файлы с расширением .html в текущей директории:-
sed -i '/<\/head>/ i <meta http-equiv="Content-Type" content="text\/html; charset=utf-8">' *.html
-
sed -i -r "s/\r//g" *.html
Второй sed нужен чтобы поудалять символ возврата каретки с ASCII-кодом 13 в конце строк, который почему-то появляется в результате работы первого sed-а.
-
- Удаление из файла первых нескольких строк до тех пор, пока не встретиться пустая строка. Такое часто бывает нужно при обработке писем – если нужно отделить заголовок письма от его тела:
-
$cat test.txt
-
Some text in mail header.
-
Another text line in mail header.
-
And so on…
-
-
Here starts mail body.
-
Some text in mail body.
-
Use sed to make things nice :)
-
-
$sed '1,/^$/ d' test.txt
-
Here starts mail body.
-
Some text in mail body.
-
Use sed to make things nice :)
Здесь видно, что первые три строки были удалены. Шаблон /^$/ означает пустую строку (символ ^ совпадает с началом строки, а символ $ – с концом строки. Так как между ними ничего нет, то строка пустая). Выражение 1,/^$/ означает диапазон строк с 1-ой до пустой включительно. Оператор «d» – удаление.
-
- Получение заголовка usenet/email письма (удаление всего после 1-ой пустой строки):
-
sed '/^$/q' /tmp/mail_message
-
- Вставить пустую строку перед строкой, совпадающей с регулярным выражением “regex”:
-
sed '/regex/{x;p;x;}' test.txt
-
- Вставить пустую строку после строки, совпадающей с регулярным выражением “regex”:
-
sed '/regex/G' test.txt
-
- Удаление комментариев и пустых строк. Допустим, мы хотим в каком-то конфиге посмотреть только самую его суть, не отвлекаясь на комментарии и объяснения что означают используемые опции. Для этого используем такую простую команду:
-
$egrep -v "^#" /etc/snmp/snmpd.conf | sed '/^$/ d'
В результате grep уберет из файла /etc/snmp/snmpd.conf строки, в начале которых стоит символ решётки (но оставит пустые строки), а следующий за ним sed найдёт и удалит строки, у которых между началом и концом строки ничего нет.
-
- Замена текста. Для этого используется оператор s///:
-
$cat test.txt
-
I want to have nice house with 4 rooms.
-
-
$sed "s/\(nice\)/very \1/" test.txt | sed "s/[0-9]/12/"
-
I want to have very nice house with 12 rooms.
В операторе замены s (чаще всего используется его вариант s///) между 1-ым и 2-ым слешем указывается шаблон, который нужно найти для замены, а между 2-ым и 3-им слешем – текст, НА который нужно заменить шаблон. Если в шаблоне используются круглые скобки (их нужно экранировать обратными слешами), то текст между скобками будет доступен для использования во второй части оператора (это называется backreference). Для вставки текста, заключенного в 1-ую пару скобок, применяется конструкция \1, для текста между второй парой скобок – \2 и т.д. Символ амперсанда (&) в правой части используется для вставки текста, который совпал с регулярным выражением в левой части. Вместо слеша в операторе s можно использовать любой другой символ, например:
-
$ echo "I want to have a nice house with 4 rooms." | sed "s|nice|very &|"
-
I want to have a very nice house with 4 rooms.
Если нужно заменить все вхождения шаблона в строке, а не только первое, то нужно использовать флаг g (от слова global):
-
$ echo "AAABBBCCC" | sed "s/A/X/"
-
XAABBBCCC
-
$ echo "AAABBBCCC" | sed "s/A/X/g"
-
XXXBBBCCC
Если нужно заменить не первое вхождение шаблона в тексте, а какое-то N-ое, то нужно использовать флаг N (который также можно комбинировать с флагом g — в этом случае заменится N-ое И все последующие совпадения шаблона в тексте):
-
$ echo "AAAA-BBBB-CCCC" | sed "s/A/X/2"
-
AXAA-BBBB-CCCC
-
$ echo "AAAA-BBBB-CCCC" | sed "s/A/X/3"
-
AAXA-BBBB-CCCC
-
$ echo "AAAA-BBBB-CCCC" | sed "s/A/X/2g"
-
AXXX-BBBB-CCCC
-
- Удаление HTML-тегов
-
sed -e :a -e 's/<[^>]*>//g;/</N;//ba' index.html
Фрагмент ;/</N;//ba предназначен для удаления тегов, растянутых на несколько строк. Без него будут удаляться только те теги, которые были закрыты угловой скобкой в той же стройке, в которой были открыты.
-
Популярность: 4%

Комментариев: 1
Чтобы быть всегда в курсе здесь происходящего, Вы можете подписаться на RSS feed для комментариев на эту заметку.
Еще один одна полезный рецепт:
вставка текста SomeText в начало последней строки файла:
sed -i -r «$,$ s/(.*)/SomeText \1/» file.txt