Příkazy sedu načítáme z řádky nebo ze souboru:
sed 'příkazy' soubor1 soubor2 ...
sed -f 'soubor_s_příkazy' soubor1 soubor2 ...
sed -e 'příkazy' -f 'soubor_s_příkazy' soubor1 soubor2 ...
Důležitý přepínač je -n – nevypisovat defaultně na výstup. Další je -r zapínající extended regulární výrazy. Příkazy od sebe můžeme oddělovat středníky nebo znaky nového řádku. Syntaxe příkazů sedu je vždy následující:
[adresa1[,adresa2]]příkaz[parametry]
Pokud není uvedena adresa, provede se příkaz pro každý řádek. Pokud je uvedena pouze adresa1, provede se příkaz pro řádek odpovídající adrese. Pokud je uvedena i adresa2, provede se příkaz pro všechny řádky mezi adresou1 a adresou2 (včetně). Adresa může být číslo řádku, $ pro poslední řádek nebo /regexp/.
Sed pracuje se dvěma prostory – pattern space (PS), do kterého se načítá každá nová řádka a hold space (HS), s jehož obsahem manipulujeme sami. Nic dalšího nemáme, žádné proměnné apod. Pouze příkazy pro manipulaci s obsahem pattern space a hold space. Seznam příkazů naleznete v manuálové stránce sedu. Nejpoužívanější jsou:
n ... vypsání současného PS (není-li -n) a načtení
dalšího řádku do PS
N ... připojení dalšího řádku do PS
d ... smazání PS, začne od začátku
D ... smazání prvního řádku PS, začne od začátku,
ale nenačítá vstup, je-li PS neprázdný
p ... vypíše PS na standardní výstup
P ... vypíše první řádek PS
h ... kopíruje PS do HS
H ... připoujuje PS do HS
g ... kopíruje HS do PS
G ... připojuje HS do PS
x ... prohazuje obsah PS a HS
:l ... značka l
bl ... skočí na značku l
tl ... skočí na značku l, pokud došlo od posledního
načtení řádku k úspěšnému nahrazení s///
Tl ... skočí na značku l, pokud nedošlo od posledního
načtení řádku k úspěšnému nahrazení s///
s/// ... nahrazení (viz minulá hodina)
y/// ... transliterace (jako tr, bez rozsahů)
q ... ukončí zpracování vstupu a vypíše PS (není-li -n)
sed -n 'p;n'
sed '1,/^$/d'
sed -rn '/^(From:|To:|Subject:)/{p;d};1,/^$/!p'
sed -r 's#([.!?]) *#\1\n#g'
Těžší varianta:
sed -rn 'H;${x;s#\n# #g;s#([.!?]) *#\1\n#g;p}'
sed -n 'x;1!H;${x;p}'
#!/bin/sed -f
:l
s/10/01/g
tl
sed -r 's/\b[A-Za-z]{1,3}\b//g'
sed -r 's/^.*('"$REGEX"').*$/\1/g'
Nicméně, tento program má dva problémy. Vypíše i ty řádky, na kterých se daný
vzor vůbec nevyskytuje a kvůli žravosti * neodpovídá vypsaná část
řádku nejdelšímu odpovídajícímu úseku (pokud REGEX sám obsahuje * či
+). První zmíněný problém vyřešíme jednoduše.
sed -rn 's/^.*('"$REGEX"').*$/\1/;T;p'
Pokud by se navíc v REGEXu vyskytovaly backreference, musíme jejich čísla
zvýšit o jedna (protože jsme přidali jednu vnější závorku navíc). To nás ale
pro fixní regex netrápí. Řešení druhého problému je komplikovanější. Mimo sed
by nám mohly pomoct perlové regulární výrazy, které obsahují tzv. líný
kvantifikátor *?
. S našimi prostředky budeme muset přizpůsobit
řešení konkrétnímu regulárnímu výrazu. Např. pokud bychom hledali
a.*b
, řešení by vypadalo následovně:
sed -rn 's/[^a]*(a.*b).*$/\1/;T;p'
V některých případech bychom mohli vytvořit regulární výraz odpovídající
převráceným řetězcům k těm, které odpovídají výrazu REGEX a pomocí
rev
poté odřezat vždy neodpovídající konce.
#!/bin/sed -nrf
# Najdeme-li prázdný řádek, uložíme do HS \n
/^\s*$/ {
s/.*/\n/
h
}
# Najdeme-li neprázdný řádek:
/\S/ {
x
/^\n$/ { # Pokud byl v HS \n, smažeme ho, vypíšeme
s/.*// # prázdný řádek a nakonec vypíšeme samotný
p # neprázdný řádek
}
x;p
}
$ { # Pokud byl poslední řádek prázdný, vypíšeme ho
/^\s*$/ {
s/.*//
p
}
}
sed '/\n/!G;s/\(.\)\(.*\n\)/&\2\1/;//D;s/.//'