24. 5. 1999 | ![]() ![]() ![]() ![]() ![]() |
V minulém díle jsem popsal skript na dávkovou změnu textu. Použil jsem při tom perl, find a vi. V tomto článku ukážu dva další způsoby, jak udělat totéž jinými způsoby, přičemž algoritmus Ondry Surého je nejefektivnější. Berte tyto tři možnosti jako důkaz flexibility unixu.
První reakci jsem obdržel od Honzy Dušáka (omlouvám se, jestli se mi nepovedl převod z cestiny do češtiny). Jeho skript používá pouze kombinace perlu a find:
find . -name "*.html" -exec perl -i.bak -p -e "s/stare/nove/" {} ;
Co to dělá? Kdykoliv find najde soubor, který splňuje zadaná pravidla, spustí perl ve speciálním modu. A ten pomocí svých interních regulárních výrazů provede záměnu. K tomuto skriptu bych měl výhradu, že se při každém nalezení souboru spouští perl, což je intepret. A ne zrovna malý. Navíc kdysi jsem psal nějakou aplikaci v perlu a rychlost vnitřních regulárních výrazů mě zklamala. Ale to se mohlo mezitím změnit.
Další dopis mi napsal Ondra Surý. Ten měl výhrady k volbě programů (eufemicky řečeno). Místo nich navrhl použít sed a shell.
#!/bin/sh
for $file in `find . -name "*.html"`; do
echo -n "Zpracovávám soubor $file";
mv $file $file.bak;
cat $file.bak | sed -e "s/XYZ/ABC/" > $file
echo -n "hotovo."
done
Tento skript je ve své podobě velmi podobný mému původnímu řešení. Místo perlu ale používá shell (rychlejší start, zabírá méně paměti) a místo vi program sed (rychlejší běh, méně použité paměti).
Jednočlenná komise ve složení Leoš Literák se jednomyslně shodla, že vítězem se stal Ondra Surý. Jeho řešení je nejefektivnější a nejpřehlednější (a já se po večerech budu učit programovat v shellu).
Tak mě napadá, co udělat menší soutěž. Pošlete mi své skripty, já je porovnám, otestuji a výsledky zveřejním. Skript má
Autor: Leoš Literák (jiné články tohoto autora)
Sekce: Praxe
Související články:
25. 5. 1999 21:16:07 - K uvedeným příkladům a hlavně ... (Jiří Svatoň)
K uvedeným příkladům a hlavně potom k vyhlášené soutěži mám jednu připomínku. Dokud byl uveden jenom první příklad, bral jsem to jako jednoduchou ukázku, která sice leccos opomněla, ale pro demonstrační účely stačí. Ale vyhlášením soutěže se situace poněkud mění. Tady by uz mělo jít o skutečně použitelný script.
Problém je v tom, že script je sice ve všech ukázkách deklarován pro použití na html souborech, ale pomíjí základní vlastnost HTML, tedy že oddělovačem může být jakékoliv bílé místo včetně NOVÉHO ŘÁDKU. A přitom varianta s vi i se sed (a myslím, že i ta s perlem) pracují řádkově, tedy načtou ze vstupu JEDNU ŘÁDKU a nad ní provedou náhradu.
I když použiji jako nahrazovaný vzor regulární výraz, ve kterém místo všech mezer uvedu 'nejméně jedno bílé místo', zpracuje mi to sice správně podobu <a(mezera)href, <a(mezera)(mezera)href a pod., ale selže to na <a(nová řádka)href :-(
Narazil jsem na to teď, když se snažím na serveru s mnoha sty stránkami nahradit několikařádkový starý kód Mr.Lin(x)e novým (navíc nevím, jak mi ho za tu dobu různé editory při zalamování přeformátovaly)...
26. 5. 1999 10:43:28 - Re: K uvedeným příkladům a hlavně ... (Leos literak)
K prikladu s (A href='sdfsd'): Toto se da vyresit
jednoduse zmenou regularniho vyrazu na
s/href='sdfsd' -) takto se vezme jen odkaz a nove
radky mezi (a a href nejsou problem.
6. 6. 1999 23:57:43 - Re: K uvedeným příkladům a hlavně ... (Jiří Svatoň)
Teď poněkud uhýbáte. Ten příklad s (a href=) jsem zvolil jenom pro jednoduchost. Jak jsem uz psal, jde mi obecně o víceřádkové náhrady, přesněji o náhrady, kde konec řádku nehraje roli (stejně jako v HTML kódu).
Mimochodem, já v tom mém textu nikde nepsal, ze v tom (a href=) chci měnit jenom obsah toho href, co když jsem chtěl místo celého tagu (a href=) dát něco jiného (třeba SSI sekvenci, nebo javascript, které ho vygenerují) :-)
A na konci jsem úplně konkrétně psal, že jsem na to narazil při výměně kódu Mr.Lin(x)e a to je (pokud jej neznáte) náhrada starého cca pětiřádkového javascriptu za nový asi osmiřádkový...
![]() ![]() ![]() ![]() ![]() |