Nahrazování

Jedním z nejčastěji používaných příkazů editoru ex je nahrazování. Příkaz se nazývá s (substitute) a má následující tvar:
<řádky>s/<co_hledat>/<čím_nahradit>/<volby>
Jako všechny ostatní začíná určením řádků, kterých se má nahrazení týkat. Za příkazem s se uvádějí dva řetězce, jako obvykle vymezené lomítky. První určuje, jaký text má editor hledat, a druhý čím jej nahradit.

Příklad:
Kdybych chtěl v celém textu nahradit řetězec raz řetězcem dva, použil bych:
:%s/raz/dva/
Připomínám, že procento ztělesňuje všechny řádky souboru.
Takto triviální případ vás samozřejmě těžko ohromí, ale především při vyhledávání se ukazuje síla regulárních výrazů. Navíc je můžete používat hned na dvou místech: jednak ve specifikaci řádků (kde se má pravidlo použít), jednak v parametrech vyhledávání. Pokročilejší příklady uvedu později.

Volby

Účinek nahrazování lze ovlivňovat volbami, které se uvádějí za závěrečným lomítkem. Nejčastěji používané jsou dvě: g a c.

Volba g způsobí, že vim nahradí všechny výskyty řetězce na řádku. Implicitně totiž nahrazuje pouze první z nich, takže z řádku

raz raz raz dvá raz
(oblíbené vojenské zaklínadlo pro synchronizaci pochodujících) by příkaz
:s/raz/dva/
udělal
dva raz raz dvá raz
Teprve příkaz
:s/raz/dva/g
zajistí nahrazení všech slov a vznikne
dva dva dva dvá dva
Abych mluvil skutečnou pravdu, chování vim závisí na nastavení parametru gdefault. Pokud je zapnut (:set gdefault), editor implicitně nahrazuje všechny výskyty řetězce na řádku. Při použití volby g pak bude nahrazovat vždy jen první kousek na každém řádku. Vypnutý parametr (:set nogdefault) pak zajistí výše popsané chování, které je implicitní pro původní editor vi i řadu dalších programů systému Unix.

Druhá volba umožňuje potvrzování každé náhrady. Zadáte-li

:%s/raz/dva/gc
vim se pokusí nahradit všechny řetězce raz v textu, ale každý z nich nejprve předvede a dotáže se, zda jej má skutečně nahradit. Tato vlastnost je velmi užitečná, pokud se necítíte silní v kolenou a máte jisté obavy, že hledanému řetězci by mohlo vyhovět i něco navíc proti vašemu záměru. Svou odpověď můžete vybírat z obvyklých možností:
y nahradit daný výskyt
n ponechat tento výskyt v původním tvaru a pokračovat dál
[Esc] nebo q ponechat tento výskyt v původním tvaru a ukončit nahrazování
a nahradit tento a všechny následující výskyty

Komplikovanější příklady

Kdysi jsem v jednom zdrojovém textu potřeboval všechny číselné údaje vydělit deseti. To vlastně znamená vyhledat všechna čísla a před poslední číslici do nich vložit tečku. Zmíněnou akci obstará příkaz
:%s/\([0-9]*\)\([0-9]\)/\1.\2/g
Hledá skupiny číslic a ty si díky mechanismu zapamatování (kulaté závorky s lomítkem) rozdělí vždy na dvě části. První je dlouhá podle potřeby a druhá obsahuje vždy právě jednu (poslední) číslici. V nahrazovacím řetězci jen zopakuje tyto zapamatované skupiny, avšak mezi ně vloží tečku.

Nedávno jsme měnili strukturu domácích adresářů uživatelů na disku. Pro každého uživatele obsahoval soubor informace o uživatelském jméně a domácím adresáři - například

PAVEL.SATRAPA,USR:HOME\KIT\SATRAPA
Soubor byl uspořádán abecedně podle uživatelských jmen. My jsme však potřebovali seskupit uživatele podle kateder, které se projevují v cestě k domácímu adresáři za adresářem HOME (jakožto příslušník katedry informačních technologií bydlím v adresáři KIT). Potřebovali jsme tudíž vycucnout dotyčné jméno adresáře a zapsat je jako první údaj na řádku - abychom obdrželi
KIT,PAVEL.SATRAPA,USR:HOME\KIT\SATRAPA
Takový soubor pak stačí protáhnout standardním programem sort a členové jednotlivých kateder se rázem ocitnou pospolu. Potřebnou transformaci obstará
:%s/\^(.*:HOME\\\)\([^\\]*\)/\2,\1\2
Při vyhledávání si příkaz zapamatuje vše od začátku řádku až po řetězec :HOME\ (jelikož lomítko má speciální význam, musí se v hledaném řetězci zdvojit). Pod číslem 2 se následně zapamatuje řetězec znaků, odlišných od lomítka (jinými slovy celý název adresáře až po následující lomítko). V nahrazovacím řetězci se nejprve vypíše tento název adresáře, za ním čárka a pak beze změny obě zapamatované části textu.
<-- predchozi  [obsah]  dalsi -->
© 1997, 1998 Pavel Satrapa