Obcování s ďáblem - další finty s příkazem sed - MujMAC.cz - Apple, Mac OS X, Apple iPod

Odběr fotomagazínu

Fotografický magazín "iZIN IDIF" každý týden ve Vašem e-mailu.
Co nového ve světě fotografie!

 

Zadejte Vaši e-mailovou adresu:

Kamarád fotí rád?

Přihlas ho k odběru fotomagazínu!

 

Zadejte e-mailovou adresu kamaráda:

Soutěž

Sponzorem soutěže je:

IDIF

 

Jaký fotograf/ka získal/a cenu za nejpopulárnější příspěvek v Nikon Photo Contest?

V dnešní soutěži hrajeme o:

Seriály

Více seriálů



Informace

Obcování s ďáblem - další finty s příkazem sed

10. ledna 2002, 00.00 | Minule jsme se seznámili se základy příkazu sed; dnes se podíváme na některé jeho další vlastnosti — především možnost omezit platnost příkazu jen na některé řádky.

Minule jsme se seznámili se základy příkazu sed; dnes se podíváme na některé jeho další vlastnosti — především možnost omezit platnost příkazu jen na některé řádky.

Co je v sedu "adresa"

Příkaz sed dovoluje před každým příkazem uvést tzv. adresu, která určuje řádky, na něž se má příkaz aplikovat. Pokud adresa není uvedena, příkaz se — jak už vlastně víme — použije na všechny řádky.

Nejjednodušší adresou je prostě číslo řádku: chceme-li nějaký příkaz provést pouze na řádku zadaného čísla, stačí před něj vložit číslo požadovaného řádku:

93 /tmp> sed -e '2y/eai/EAI/' test
Jednoduchy testovaci text
pro ukAzky prAcE s prIkAzEm sEd.
To je zatim vsechno...
94 /tmp> 

Můžeme určit také poslední řádek pomocí speciálního "čísla" '$':

94 /tmp> sed -e '$s/$/KONEC!/' test
Jednoduchy testovaci text
pro ukazky prace s prikazem sed.
To je zatim vsechno...KONEC!
95 /tmp> 

Uvědomte si, jaký je rozdíl mezi oběma použítými znaky '$'!

Asi nejčastější adresa s nejbohatším použitím však je regulární výraz, umístěný mezi dvojicí lomítek. Jestliže řádek regulárnímu výrazu odpovídá (v přesně stejném významu, jako kdybychom výraz použili v příkazu grep), příkaz se provede; jinak se příkaz ignoruje.

Dejme tomu, že bychom chtěli příkaz omezit jen na řádky, které obsahují nějaké velké písmeno; pak před něj stačí umístit adresu "/[A-Z]/":

97 /tmp> sed -e '/[A-Z]/s/^/JETAM /' test
JETAM Jednoduchy testovaci text
pro ukazky prace s prikazem sed.
JETAM To je zatim vsechno...
98 /tmp> 

Adresy ovšem můžeme i kombinovat. Je-li příkaz uveden dvojicí adres, oddělených čárkou, bude proveden nad všemi řádky počínaje tím, který je určen první adresou, a konče tím, který je určen tou druhou.

Podívejme se na jednoduchý příklad, který doplní text "I~O" ke všem řádkům počínaje tím, který obsahuje 'i', a konče tím, který obsahuje 'o'. Abychom měli řádků více, rozdělíme nejprve slova textu na jednotlivé řádky příkazem, který známe už od minula:

100 /tmp> sed -e 'y/ /\n/' test | sed -e '/i/,/o/s/$/ I~O/'  
Jednoduchy
testovaci I~O
text I~O
pro I~O
ukazky
prace
s
prikazem I~O
sed. I~O
To I~O
je
zatim I~O
vsechno... I~O
101 /tmp> 

Dnes nás samozřejmě zajímá až ten druhý příkaz sed.

Poslední šikovná finta, o které se v tomto odstavci zmíníme, je vykřičník: jestliže jej umístíme mezi adresu a příkaz, příkaz se provede na všech ostatních řádcích — právě na těch, na kterých by se normálně nedělal.

Porovnejte např. příklad z řádku 97 s tímto:

101 /tmp> sed -e '/[A-Z]/!s/^/JETAM /' test
Jednoduchy testovaci text
JETAM pro ukazky prace s prikazem sed.
To je zatim vsechno...
102 /tmp> 

nebo příklad z řádku 100 s tímto:

102 /tmp> sed -e 'y/ /\n/' test | sed -e '/i/,/o/!s/$/ NE I~O/'
Jednoduchy NE I~O
testovaci
text
pro
ukazky NE I~O
prace NE I~O
s NE I~O
prikazem
sed.
To
je NE I~O
zatim
vsechno...
103 /tmp> 

Mimochodem, chceme-li uvnitř adresy, již representuje regulární výraz, použít lomítko, můžeme požít jiný znak — jen před jeho prvním výskytem musíme použít escape znak (obrácené lomítko). Adresa "\|//|" tedy např. specifikuje všechny řádky, které obsahují dvojici lomítek.

Paměť regulárních výrazů

Pro pohodlí uživatelů si sed pamatuje vždy naposledy použitý regulární výraz. Pokud tedy např. chceme použít v příkazu 's' stejný výraz, jaký byl v odpovídající adrese (což je poměrně častý případ), asi takto:

/a.b/s/a.b/c/

můžeme regulární výraz v příkazu 's' prostě vynechat. Příkaz sed v takovém případě použije poslední výraz z paměti. Následující řádek je tedy plně ekvivalentní minulému příkladu:

/a.b/s//c/

Příkazové soubory

O příkazových souborech jsme si řekli už minule: je-li sada příkazů pro sed složitější, vyplatí se ji uložit do samostatného souboru, a ten příkazu sed předat pomocí přepínače -f. Nyní to tak budeme pro lepší přehled dělat; poslední příklad z minulého dílu

103 /tmp> sed -e 'y/eai/EAI/' -e 's/[A-Z]/(&)/g' -e 's/^(/[/' test
[J)(E)dnoduchy t(E)stov(A)c(I) t(E)xt
pro uk(A)zky pr(A)c(E) s pr(I)k(A)z(E)m s(E)d.
[T)o j(E) z(A)t(I)m vs(E)chno...
104 /tmp> 

bychom tedy dnes zobrazili jako samostatný script — třeba takto:

104 /tmp> cat > script.sed                                          
y/eai/EAI/
s/[A-Z]/(&)/g
s/^(/[/
104 /tmp> sed -f script.sed test                                  
[J)(E)dnoduchy t(E)stov(A)c(I) t(E)xt
pro uk(A)zky pr(A)c(E) s pr(I)k(A)z(E)m s(E)d.
[T)o j(E) z(A)t(I)m vs(E)chno...
105 /tmp> 

Spojování příkazů do skupin

V sedu můžeme více příkazů spojit do jedné skupiny, která je celá podmíněna adresou — celá se tedy provede jen nad odpovídajícími řádky. Odpovídající syntaxe je jednoduchá: příkazy se prostě uzavřou do složených závorek.

Podívejme se např. pro srovnání nejprve na případ, kdy omezíme třeba jen na druhý řádek pouze první příkaz z našeho jednoduchého skriptu:

105 /tmp> cat script.sed 
2y/eai/EAI/
s/[A-Z]/(&)/g
s/^(/[/
106 /tmp> sed -f script.sed test
[J)ednoduchy testovaci text
pro uk(A)zky pr(A)c(E) s pr(I)k(A)z(E)m s(E)d.
[T)o je zatim vsechno...
107 /tmp> 

a na případ, kdy na druhý řádek omezíme oba dva první příkazy (sdružené do skupiny):

107 /tmp> cat script.sed        
2{y/eai/EAI/
  s/[A-Z]/(&)/g
}
s/^(/[/
108 /tmp> sed -f script.sed test
Jednoduchy testovaci text
pro uk(A)zky pr(A)c(E) s pr(I)k(A)z(E)m s(E)d.
To je zatim vsechno...
109 /tmp> 

Mimochodem, pozorní čtenáři si možná uvědomili, že v našem příkladu bychom mohli stejného efektu dosáhnout vlastně snáze — stačilo by na druhý řádek omezit oba dva příkazy, první i druhý:

109 /tmp> cat script.sed        
2y/eai/EAI/
2s/[A-Z]/(&)/g
s/^(/[/
110 /tmp> sed -f script.sed test
Jednoduchy testovaci text
pro uk(A)zky pr(A)c(E) s pr(I)k(A)z(E)m s(E)d.
To je zatim vsechno...
111 /tmp> 

Dnes se proto rozloučíme malým kvízem pozornosti: co myslíte, platí tohle obecně? Jinými slovy, máme-li skupinu příkazů, která je jako celek omezena nějakou adresou, můžeme vždy dosáhnout přesně stejného efektu tím, že skupinu zrušíme, a tutéž adresu použijeme pro všechny její příkazy?

Příště...

...si samozřejmě zodpovíme otázku z minulého odstavce. Kromě toho si ukážeme rozsáhlejší příklad sedového scriptu.

Obsah seriálu (více o seriálu):

Tématické zařazení:

 » Rubriky  » Informace  

 » Rubriky  » Agregator  

 » Rubriky  » Software  

 

 

 

 

Přihlášení k mému účtu

Uživatelské jméno:

Heslo: