Linux: Kniha kouzel, 2.15 (1. března 2025)
Veškerá moc příkazové řádky/příkazového řádku přehledně, pro začátečníky i pokročilé

21. Sed

Vývoj vanilkové příchuti Linuxu: Knihy kouzel byl 1. března 2025 ukončen. Tento text je zachován jako historický, ale chyby již nejsou opravovány. Odnože projektu pod kompatibilní licencí jsou vítány.

1. Úvod

„Sed“ je nástroj příkazové řádky pro editaci textového souboru (txt či txtz) po záznamech. Nejčastěji je užíván díky své schopnosti testovat záznamy vůči regulárním výrazům a nahrazovat jejich shody. Ve skutečnosti nenabízí o mnoho víc, takže tato kapitola bude spíše stručná. Jeho hlavními výhodami oproti konkurečním nástrojům jsou rychlost zpracování, přítomnost v prakticky každé instalaci linuxu, stoprocentní podpora UTF-8 a mimořádně úsporná syntaxe.

Sed pracuje tak, že v cyklu načítá záznamy ze vstupních souborů a na každý záznam spustí skript (zadaný typicky přímo na příkazové řádce, jen vzácně se ukládá do samostatného souboru).

GNU Sed je vyvíjen v rámci projektu GNU.

2. Definice

  • Prostor (space) je v Sedu oblast, do které se ukládají textové záznamy nebo jiné hodnoty. Existují pouze pevně definované prostory.
  • Pracovní prostor (pattern space) je prostor, do kterého se normálně na začátku každého cyklu přiřadí další načtený záznam. (Může však obsahovat i více záznamů.) Existují dva způsoby, jak na pracovní prostor nahlížet: většina příkazů ho vidí jako uspořádaný seznam záznamů, kde každý záznam je uveden včetně svého ukončovače; tzn. např. „ab\n“ a „cd\n“. Výjimkou je příkaz „s“, který vidí pracovní prostor jako řetězec, kde jsou tyto záznamy spojeny dohromady, ovšem ukončovač posledního záznamu je odsunut mimo. (Proto jsou-li např. v pracovním prostoru dva výše uvedené záznamy, příkaz „s/.*//“ skončí stejně vypsáním jedné prázdné řádky, protože závěrečný ukončovač zůstává mimo dosah příkazu „s“.)
  • Paměť (hold space) je pomocný prostor, do kterého lze záznamy z pracovního prostoru přenést či je tam připojit.
  • Příznak je booleovská proměnná používaná k podmíněným skokům (viz příkazy „s“, „t“ a „T“).
  • Vstupní data sed rozdělí na záznamy, což jsou ve výchozím stavu řádky (ukončené znakem „\n“), ale s parametrem „-z“ to budou bloky znaků ukončené nulovým bajtem („\0“).
  • Počítadlo záznamů je číselná proměnná – na počátku má hodnotu 0 a inkrementuje se pokaždé, když je ze vstupu načten záznam (tzn. pro první záznam už má hodnotu 1). Nikdy se nenuluje.

2/1 Cyklus sedu

Sed provádí zpracování vstupních souborů v těchto krocích:

1) Smaž pracovní prostor.

2) Pokud je na vstupu další záznam, načti ho a připoj na konec pracovního prostoru; jinak skonči.

3) Procházej skript, vyhodnocuj podmínky a vykonávavej odpovídající příkazy.

4) Vypiš pracovní prostor včetně odděleného ukončovače záznamu. (Tento krok se často z postupu odstraňuje voláním sedu s parametrem „-n“. Rovněž příkaz „d“ ho potlačí.)

5) Pokud nebyl v tomto cyklu skriptu proveden příkaz „q“, jdi zpět na krok 1.

2/2 Obecný tvar příkazu

Příkazy sedu mají obecný tvar:

podmínka[!]příkaz

Vykřičník neguje logickou hodnotu podmínky.

Je-li příkazů víc, odděluje je konec řádky („\n“), není-li odzvláštněn zpětným lomítkem. Pokud neposlední z příkazů neočekává jako parametr název souboru či obecný text, lze je oddělit také středníkem.

Místo jednotlivého příkazu může být také blok příkazů, které pak mohou mít svoje vlastní podmínky. V takovém případě sed nejprve otestuje podmínku bloku; není-li splněna, celý blok se přeskočí. Je-li splněna, sed do bloku vstoupí a jeho obsah vykoná, jako by podmíněn nebyl. Bloky lze zanořovat. Příklad, jak může vypadat blok:

/^a/!{
/test/d
/x/s/.*/&*/
}

2/3 Řetězec náhrady

V příkazu „s“ se uvádí „řetězec náhrady“, tedy řetězec, který definuje, za co se mají nahradit shody uvedeného regulárního výrazu. V tomto řetězci mají zvláštní význam znaky „\“, „&“ a znak ohraničující daný regulární výraz (obvykle „/“ či „!“); všechny lze odzvláštnit zpětným lomítkem.

Zvláštní významy znaků jsou následující: Za znak „&“ se dosadí původní text celé shody; za kombinace „\1“ až „\9“ se dosadí text podshody první až deváté skupiny v regulárním výrazu (skupiny se číslují podle pozice otevírací závorky). Za „\n“ se dosadí znak konce řádku, pro vložení nulového bajtu použije kombinaci „\x00“.

V řetězci náhrady také mohou být přepínače konverze velikosti písmen: „\L“ konvertuje následující znaky na malá písmena, „\U“ na velká písmena a „\E“ tuto konverzi vypne. „\l“ a „\u“ fungují analogicky, ale uplatní se jen na jeden následující znak.

3. Zaklínadla

3/1 Podmínky (uvádějí se před příkaz)

Kteroukoliv podmínku lze negovat uvedením vykřičníku za podmínku.

@každý záznam#1
prázdný řetězec
@záznam odpovídající regulárnímu výrazu (alterantivy)#2
/regulární výraz/
\!regulární výraz!
@záznam odpovídající regulárnímu výrazu bez ohledu na velikost písmen (alterantivy)#3
/regulární výraz/I
\!regulární výraz!I
@rozsah mezi dvěma řádky danými čísly záznamů#4
první-zahrnutý,poslední-zahrnutý
@rozsah mezi dvěma řádky odpovídajícími regulárním výrazům#5 (1)
/reg. výraz pro první záznam/[I],/reg. výraz pro poslední záznam/[I]
@konče/počínaje určitým záznamem#6
1,poslední-zahrnutý
první-zahrnutý,$
@první/poslední záznam#7
1
$
@dva první/poslední záznamy#8
1,2
@všechny záznamy až po první záznam odpovídající regulárnímu výrazu včetně#9
0,/regulární výraz/[I]
@záznam odpovídající regulárnímu výrazu a N následujících#10
/regulární výraz/[I],+N
@rozsah od záznamu odpovídajícího regulárnímu výrazu po následující záznam, jehož číslo je celočíselným násobkem N#11
/regulární výraz/[I],~N
@liché/sudé záznamy#12
1~2
2~2
@každý třetí záznam, počínaje sedmnáctým#13
17~3

4. Zaklínadla: Příkazy

4/1 Operace s pracovním prostorem

@provést náhradu v pracovním prostoru (alternativy)#1 (2)
s/regulární výraz/řetězec náhrady/[volby]
s!regulární výraz!řetězec náhrady![volby]
@načíst další záznam do pracovního prostoru (přepsat stávající/přidat za stávající)#2
n
N
@nahradit znaky#3 (3)
y/řetězec 1/řetězec 2/
@nahradit ukončovače záznamu (\n nebo \0) kromě posedního#4
s/\n/řetězec náhrady/g
s/[\x00]/řetězec náhrady/g
@přiřadit do pracovního prostoru jeden prázdný záznam#5
z
@odstranit první záznam#6

4/2 Skoky

@na konec skriptu (nevypisovat pracovní prostor/normálně/nezačínat další cyklus)#1
d
b
q
@podmíněný skok (skočit, pokud je příznak 1/pokud je 0)#2 (4)
t[návěští]
T[návěští]
@návěští pro skoky#3 (5)
:návěští
@skok na návěští#4
bnávěští
@okamžitě ukončit zpracování#5
Q
@je-li v pracovním prostoru víc záznamů, smazat první z nich a skočit na začátek skriptu; jinak se chová jako příkaz „d“#6
D

4/3 Výpis na výstup

@vypsat pracovní prostor na standardní výstup (všechny záznamy/jen první záznam)#1
p
P
@vypsat pracovní prostor do souboru (všechny záznamy/jen první záznam)#2 (6)
wjméno/souboru
Wjméno/souboru
@vypsat číslo záznamu (jako záznam)#3
=
@vypsat konkrétní záznam#4 (7)
i\
[řádek záznamu\]
poslední řádek záznamu

4/4 Operace s pamětí

@přiřadit obsah pracovního prostoru do paměti (hold)#1
h
@přiřadit obsah paměti do pracovního prostoru (get)#2
g
@vyměnit obsah pracovního prostoru a paměti#3
x
@připojit obsah pracovního prostoru na konec paměti#4
H
@připojit paměť na konec pracovního prostoru#5
G

4/5 Komentář

@komentář#1
# komentář do konce řádky

5. Parametry příkazů

5/1 sed

sed parametry [-e] 'skript' [vstupní-soubor]
sed parametry -f soubor-se-skriptem [vstupní-soubor]
[sudo] sed -i parametry [-e] 'skript' soubor
[sudo] sed -i parametry -f soubor-se-skriptem soubor
☐ -EPoužije rozšířené regulární výrazy místo základních. (Tento parametr doporučuji důsledně používat, kdykoliv ve skriptu hodláte použít regulární výraz!)
☐ -nOdstranit z cyklu automatické vypisování pracovního prostoru.
☐ -zZáznamy jsou ukončeny „\0“ místo „\n“.
☐ -iMísto vypsání na výstup přepíše výstupem vstupní soubor.
☐ --debugNa výstup vypíše čitelné ladicí informace o činnosti skriptu.
☐ -uZe vstupu načítá jen minimální množství dat.

6. Instalace na Ubuntu

GNU sed je základní součástí Ubuntu přítomnou i v minimální instalaci.

7. Ukázka

@skript.sed#1
/no/d
# pokud obsahuje „1“, třetí velké či malé „x“ uzavřít do závorek,
# ne však na řádcích 7 až 12
7,12!{/1/s/x/(&)/3i}
# liché řádky velkými písmeny, před sudé pomlčku
2~2s/.*/ - &/
1~2s/.*/\U&/
p
# chybové hlášení, pokud stejná řádka obsahuje jablko i hrušku
/jablko/I{/hruška/I{i\
Chyba: nemíchejte jablka s hruškami!
}}
@volání#2
sed -nE -f skript.sed
a pište nějaké řádky textu. Sed ukončíte zkratkou Ctrl+D.

8. Tipy a zkušenosti

  • Programovat v sedu cokoliv složitějšího je namáhavé, nepraktické a náchylné na chyby. Pokud vám nestačí jen několik základních příkazů, je mnohem rozumnější použití složitějších nástrojů jako „GNU awk“ či „Perl“.
  • Skripty v sedu dovedou být extrémně nesrozumitelné. Dovedli byste na příklad říci, co udělá „sed -E '\!testy!I!s!s!x\!!i'“?
  • Malé textové soubory je často výhodné zpracovat najednou zadáním parametru „-z“. Když vstupní soubor neobsahuje nulový bajt, sed v takovém případě načte celý soubor jako jeden záznam.

9. Další zdroje informací

10. Zákulisí kapitoly

V této verzi kapitoly chybí:

  • nic

Tato kapitola záměrně nepokrývá:

  • nic
1 Poznámka: tento rozsah zahrnuje v sedu vždy alespoň dva záznamy. Pokud už první záznam rozsahu odpovídá regulárnímu výrazu pro poslední záznam, sed to ignoruje!
2 Volby mohou být: „g“ (nahradí všechny shody), kladné celé číslo (nahradí pouze tolikátou shodu), „i“ (nebude rozlišovat velká a malá písmena). Volby lze skombinovat, např. „2i“. V případě, že příkaz „s“ najde požadovanou shodu, nastaví příznak na hodnotu 1; v opačném případě příznak nemění(!).
3 Řetězce musejí mít přesně stejnou délku. Příkaz „y“ projde pracovní prostor znak po znaku a každý znak, který se nachází v řetězci 1 nahradí znakem na stejné pozici v řetězci 2. Vždy provede pouze jednu náhradu, takže tento příkaz je možno využít i k prohození dvou znaků.
4 Příkazy t a T příznak nulují vždy, i když ke skoku nedojde!
5 Návěští je příkaz, ale nepřijímá „podmínku“.
6 Poznámka: pokud soubor existuje, před prvním zápisem bude vyprázdněn!
7 Pozor, jednotlivé řádky se vždy oddělí znakem „\n“, ale ukončí se aktuálním ukončovačem záznamu („\n“ nebo „\0“).
[BY-SA]

Veškerý obsah této stránky (text, obrázky, zdrojový kód) je možno upravovat a šířit pod podmínkami licence Creative Commons Attribution-ShareAlike 4.0 International. Upozorňuji, že uvedená licence vyžaduje uvedení seznamu autorů, licence a zdroje a poskytnutí stejné či kompatibilní licence k provedeným změnám, jsou-li nějaké. Příslušné údaje jsou dostupné na stránce „Přehled autorů“. Šíření obsahu bez těchto údajů nebo šíření upravené verze bez poskytnutí adekvátní licence k provedeným úpravám je pravděpodobně porušení licenčních podmínek a může být postihováno. Poskytování zdrojového kódu při šíření není touto licencí vyžadováno.

Pro nové verze, další informace, aktuální zdrojový kód a možnost se zapojit do projektu „Linux: Kniha kouzel“ navštivte jeho repozitář na GitHubu.