Документ создан: 16.02.2010

sed

Отрицание

Содержимое sec.csv выглядит примерно так:

00:41
00:11
00:12
32
8
21:59
1:22
29:59

фактически, это время в минутах и секундах или просто в секундах. Привести его к виду hh:mm:ss можно командой:

cat sec.csv | sed -e "/:/ s/\(.*\)/00:\\1/" -e "/:/! s/\(.*\)/00:00:\\1/"

после чего данные выглядят так:

00:00:41
00:00:11
00:00:12
00:00:32
00:00:8
00:21:59
00:1:22
00:29:59

Отрицание указывается знаком "!" в конце конструкции "/:/!"

Номер строки

  • Вывести только номер строки, в которой найдено вхождение PATTERN.
    cat access_log | sed -n '/PATTERN/{=}'
  • Вывести номер строки и саму строку, в которой найдено вхождение PATTERN.
    cat access_log | sed -n '/PATTERN/{=;p;}'
  • То же, что и в предыдущем пункте, но в одну строку с разделителем ":"
    cat access_log | sed -n '/PATTERN/{=;p;}'| sed '$!N;s/\n/:/'

Примеры

UNIX SED
cat sed ':'
cat -s sed '1s/^$//p;/./,/^$/!d'
tac sed '1!G;h;$!d'
grep sed '/patt/!d'
grep -v sed '/patt/d'
head sed '10q'
head -1 sed 'q'
tail sed -e ':a' -e '$q;N;11,$D;ba'
tail -1 sed '$!d'
tail -f sed -u '/./!d'
cut -c 10 sed 's/\(.\)\{10\}.*/\1/'
cut -d: -f4 sed 's/\(\([^:]*\):\)\{4\}.*/\2/'
tr A-Z a-z sed 'y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/'
tr a-z A-Z sed 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'
tr -s ' ' sed 's/ \+/ /g'
tr -d '\012' sed 'H;$!d;g;s/\n//g'
wc -l sed -n '$='
uniq sed 'N;/^\(.*\)\n\1$/!P;D'
rev sed '/\n/!G;s/\(.\)\(.*\n\)/&\2\1/;//D;s/.//'
basename sed 's,.*/,,'
dirname sed 's,[^/]*$,,'
xargs sed -e ':a' -e '$!N;s/\n/ /;ta'
paste -sd: sed -e ':a' -e '$!N;s/\n/:/;ta'
cat -n sed '=' | sed '$!N;s/\n/ /'
grep -n sed -n '/patt/{=;p;}' | sed '$!N;s/\n/:/'
cp orig new sed 'w new' orig
hostname -s hostname | sed 's/\..*//'

Оригинал примеров здесь

Ещё пример

for i in *.txt; do sed -i "/^\^/ s/^\^\([^\^]*\)\^\^/====\1====/;/^=/ s/$/ \n^ Команда ^ Описание ^/" $i; done

Эта строка проходит в цикле по всем файлам в текущем каталоге, имена которых оканчиваются на .txt, и:

  1. /^\^/ s/^\^\([^\^]*\)\^\^/====\1====/ – если строка начинается с "^", заменить "^ Текст ^^". на "==== Текст ====";
  2. /^=/ s/$/ \n^ Команда ^ Описание ^/ — если строка начинается на "=" (а она начинается, т.к. в предыдущем пункте мы сами это сделали, и здесь условие только для того, чтобы не трогать остальные строки), заменить эту строку на неё же, плюс возврат каретки, плюс "^ Команда ^ Описание ^". Другими словами, вставить после такой строки строку содержащую "^ Команда ^ Описание ^".

Для чего это? Вот для чего. Я разбил длинный dokuwiki-файл с командами линукс на мелкие файлы. Они получились вида:

^ Анализ файловых систем ^^
| badblocks -v /dev/hda1 | проверить раздел hda1 на наличие bad-блоков |
...


Данная последовательность команд превратила их все в вид:

==== Анализ файловых систем ====
^ Команда ^ Описание ^
| badblocks -v /dev/hda1 | проверить раздел hda1 на наличие bad-блоков |
...

Удаление строки по контексту

Для удаления строки, содержащей определённый контекст, можно использовать следующую конструкцию:

sed -i "/^AUTO_SAVE/ d" notes.ini

Эта команда в файле notes.ini удаляет все строки, начинающиеся с AUTO_SAVE.

Удаление строки или нескольких строк в файле

Для удаления строки или нескольких строк в файле я использую следующую конструкцию:

sed -i '2,1d' <file_name>

Эта команда в файле <file_name> удаляет вторую строку.

Или:

sed -i '5,10d' <file_name>

Эта команда в файле <file_name> удалит десять строк начиная с пятой (включая пятую).

Объединение строк

Этот пример показывает, как можно объединить строки, разделённые возвратом каретки:

cat /etc/hosts | sed ':a; /$/N; s/\n//; ta'

Объединение двух соседних строк попарно

Объединить попарно две строки, разделённые возвратом каретки:

cat /etc/hosts | sed 'N;s/\n/ - /'

PS. Разделитель: " - ".

Перевод в верхний или нижний регистр

В верхний регистр:

echo Sed | sed 's/.*/\U&/'
SED

В нижний регистр:

echo Sed | sed 's/.*/\L&/'
sed

"Вырезать" кусок потока

Для примера возьмём результат работы dig:

$ dig ya.ru

выдаст нам


; <<>> DiG 9.7.0-P1 <<>> ya.ru
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 5252
;; flags: qr rd ra; QUERY: 1, ANSWER: 5, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
;ya.ru.                         IN      A

;; ANSWER SECTION:
ya.ru.                  4194    IN      A       87.250.251.3
ya.ru.                  4194    IN      A       93.158.134.3
ya.ru.                  4194    IN      A       213.180.204.3
ya.ru.                  4194    IN      A       77.88.21.3
ya.ru.                  4194    IN      A       87.250.250.3

;; Query time: 0 msec
;; SERVER: 192.168.2.9#53(192.168.2.9)
;; WHEN: Wed Nov 10 14:33:37 2010
;; MSG SIZE  rcvd: 103

а выполнив:

dig ya.ru | sed '0,/ANSWER SECTION:/d; /^$/q'

получим

ya.ru.                  4160    IN      A       93.158.134.3
ya.ru.                  4160    IN      A       213.180.204.3
ya.ru.                  4160    IN      A       77.88.21.3
ya.ru.                  4160    IN      A       87.250.250.3
ya.ru.                  4160    IN      A       87.250.251.3
  • 0,/ANSWER SECTION:/d - удаляет все строки потока с первой и до строки, в которой встречается "ANSWER SECTION:", включительно
  • /^$/q - как только встречается пустая строка, прекратить дальнейшую обработку.

Примеры 1

Подготовка:

cat /etc/passwd > ./test
SED Описание
cat ./test | sed -e 's/systemd/SysV/g; s/Management/Unmanaged/' К каждой строке применить две замены
cat ./test | sed -n 's/systemd/SysV/p' Вывести только заменяемые строки. -n — подавляет обычный вывод.
cat ./test | sed 's/systemd/SysV/w ./out' Вывести замену в файл out
cat ./test | sed '41s/systemd/SysV/' Произвести замену в 41 строке
cat ./test | sed '41,44s/systemd/SysV/' Произвести замену в строках с 41 по 44 включительно.
cat ./test | sed '41,$s/systemd/SysV/' Произвести замену в строках с 41 до последней включительно.
cat ./test | sed '/games/,/syslog/ s!/usr/sbin/nologin!/bin/bash!'Произвести замену в строках, которые находятся между строками, содержащими games и syslog включительно
cat ./test | sed '1c\DELETED' Заменить первую строку полность
cat ./test | sed '1,5c\DELETED' Заменить текстом строки с 1 по 5 включительно
cat ./test | sed 'y!:/!;\\!' Заменить ":" на ";", а "/" на "\"
cat ./test | sed '=' Вывести и номера строк тоже
cat ./test | sed -n '/systemd/=' Вывести номера строк, в которых встречается подстрока
Вставить в поток содержимое файла (out):
cat ./test | sed '1rout' после 1 строки
cat ./test | sed '$r out' после последней строки
cat ./test | sed '1,4rout' после 1, 2, 3 и 4 строк
cat ./test | sed '/syslog/r out' после строки, содержащей syslog
Произвести удаление строк:
cat ./test | sed '/games/,/syslog/d' которые находятся между строками, содержащими games и syslog включительно
cat ./test | sed '3,5d' с 3 по 5
cat ./test | sed '5,$d' с 5 до конца
 
Recent changes RSS feed Powered by PHP Valid XHTML 1.0 Valid CSS Driven by DokuWiki Donate