!Štítky: {program}{syntaxe}{zpracování textu} !OblíbenáZaklínadla: !ÚzkýRežim: zap
„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.
- 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.
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.
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/.*/&*/
}
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.
!ÚzkýRežim: vyp
Kteroukoliv podmínku lze negovat uvedením vykřičníku za podmínku.
# každý záznam
{prázdný řetězec}
# záznam odpovídající regulárnímu výrazu (alterantivy)
/{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)
/{regulární výraz}/I
\!{regulární výraz}!I
# rozsah mezi dvěma řádky danými čísly záznamů
{první-zahrnutý},{poslední-zahrnutý}
# rozsah mezi dvěma řádky odpovídajícími regulárním výrazům
// 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!
/{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
1,{poslední-zahrnutý}
{první-zahrnutý},$
# první/poslední záznam
1
$
# dva první/poslední záznamy
1,2
?
# všechny záznamy až po první záznam odpovídající regulárnímu výrazu včetně
0,/{regulární výraz}/[I]
# záznam odpovídající regulárnímu výrazu a N následujících
/{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
/{regulární výraz}/[I],~{N}
# liché/sudé záznamy
1~2
2~2
# každý třetí záznam, počínaje sedmnáctým
17~3
# provést náhradu v pracovním prostoru (alternativy)
// 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í(!).
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í)
n
N
# nahradit znaky
// Ř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ů.
y/{řetězec 1}/{řetězec 2}/
# nahradit ukončovače záznamu (\n nebo \0) kromě posedního
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
z
# odstranit první záznam
?
# na konec skriptu (nevypisovat pracovní prostor/normálně/nezačínat další cyklus)
d
b
q
# podmíněný skok (skočit, pokud je příznak 1/pokud je 0)
// Příkazy t a T příznak nulují vždy, i když ke skoku nedojde!
t[{návěští}]
T[{návěští}]
# návěští pro skoky
// Návěští je příkaz, ale nepřijímá „podmínku“.
:{návěští}
# skok na návěští
b{návěští}
# okamžitě ukončit zpracování
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“
D
# vypsat pracovní prostor na standardní výstup (všechny záznamy/jen první záznam)
p
P
# vypsat pracovní prostor do souboru (všechny záznamy/jen první záznam)
// Poznámka: pokud soubor existuje, před prvním zápisem bude vyprázdněn!
w{jméno/souboru}
W{jméno/souboru}
# vypsat číslo záznamu (jako záznam)
=
# vypsat konkrétní záznam
// Pozor, jednotlivé řádky se vždy oddělí znakem „\n“, ale ukončí se aktuálním ukončovačem záznamu („\n“ nebo „\0“).
i\
[{řádek záznamu}\]
{poslední řádek záznamu}
# přiřadit obsah pracovního prostoru do paměti (hold)
h
# přiřadit obsah paměti do pracovního prostoru (get)
g
# vyměnit obsah pracovního prostoru a paměti
x
# připojit obsah pracovního prostoru na konec paměti
H
# připojit paměť na konec pracovního prostoru
G
# komentář
# {komentář do konce řádky}
*# *
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}
!parametry:
- ☐ -E :: Použ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!)
- ☐ -n :: Odstranit z cyklu automatické vypisování pracovního prostoru.
- ☐ -z :: Záznamy jsou ukončeny „\0“ místo „\n“.
- ☐ -i :: Místo vypsání na výstup přepíše výstupem vstupní soubor.
- ☐ --debug :: Na výstup vypíše čitelné ladicí informace o činnosti skriptu.
- ☐ -u :: Ze vstupu načítá jen minimální množství dat.
GNU sed je základní součástí Ubuntu přítomnou i v minimální instalaci.
# skript.sed
/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í
sed -nE -f skript.sed
!: a pište nějaké řádky textu. Sed ukončíte zkratkou Ctrl+D.
!ÚzkýRežim: zap
- 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.
- Wikipedie: Sed
- HEROLD, Helmut. Awk & sed: příručka pro dávkové zpracování textu. Brno: Computer Press, 2004. ISBN 80-251-0309-9.
- Sally: Dávkový editor Sed
- Oficiální manuál (anglicky)
- An Introduction and Tutorial by Bruce Barnett (anglicky)
- YouTube: Understanding How Sed Works (anglicky)
- The Sed $HOME (anglicky)
- Computer Hope: Linux sed Command Help and Examples (anglicky)
- Oficiální stránka GNU sed (anglicky)
- Balíček (anglicky)
- TL;DR: sed (anglicky)
V této verzi kapitoly chybí:
!KompaktníSeznam:
- nic
Tato kapitola záměrně nepokrývá:
!KompaktníSeznam:
- nic
!ÚzkýRežim: vyp