Fórum Root.cz
Hlavní témata => Vývoj => Téma založeno: Jakub Řihák 09. 08. 2012, 13:32:27
-
Dobrý den, snažím se v Perlu napsat skript, který by prošel všechny XML soubory v zadaném adresáři, každý z nich otevřel a prohledal ho, zda obsahuje zadaný text (porovnávání pomocí regulárního výrazu) a následně tento vyhledaný text nahradil jiným. Zatím se mi podařilo vše, až na zapsání změněného text do příslušného souboru. Zkoušel jsem vyhledaný text nahradit pomocí substituce přímo v regulárním výrazu. Pro kontrolu jsem si nechal vypsat nalezený text i text nahrazený, ale žádná změna se v souborech neobjevila. Mohl bych vás poprosit o radu? Kód vypadá následovně:
my $adresar=<STDIN>;
my (@soubory, $jmeno, $cesta);
chomp ($adresar);
opendir(ADR,$adresar) # otevírá adresář (dle zadané cesty)
or die "Nelze otevrit $adresar!\n";
@soubory = readdir(ADR); # načítá obsah adresáře do pole @soubory
closedir(ADR);
# pro každý soubor v adresáři porovná jména s regexpem (pokud jméno začíná
# tečkou, tak přeskočí na další a vytvoří pomocí proměnných $jmeno a $adresar
# celou cestu k souboru v zadané složce
foreach $jmeno (@soubory) {
if ($jmeno =~ /^\./){
next;
}
$cesta=$adresar."\\".$jmeno;
print "$jmeno\t".$cesta."\n";
chomp ($cesta);
# otevře soubor umístěný v daném adresáři (cesta k němu je v proměnné $cesta)
open (FOXML,$cesta)
or die "Nemohu otevrit soubor $cesta\n";
# kontrolní výpis
print "Oteviram soubor............. $cesta\n\n";
# pokud najde ve vstupním souboru řádek odpovídající regexpu nahradí ho jiným
# regexpem a pro kontrololu ho vypíše do konzole
while ($radek=<FOXML>) {
if ($radek=~ s/\<kramerius:file\>(\D{2,3})(\d{2}\D{1})(\d{3})(\d{3})(\_\d{4}).jpg\<\/kramerius:file\>/\<kramerius:tiles-url\>http:\/\/imageserver.techlib.cz\/$1\/$2\/$3\/$4\/$1$2$3$4$5.jp2\<\/kramerius:tiles-url\>/g ) {
print "$radek\n\n";
}
}
}
# zavírání souboru
close (FOXML);
-
Jste si jisty ze tu zmenu do toho souboru take zapisujete? V kodu akorat menite obsah promenne do ktere je obsah radku nacteny.
-
To je pravda, zkoušel jsem tu proměnnou zapisovat do toho souboru nějak takhle:
while ($radek=<FOXML>) {
if ($radek=~ s/\<kramerius:file\>(\D{2,3})(\d{2}\D{1})(\d{3})(\d{3})(\_\d{4}).jpg\<\/kramerius:file\>/\<kramerius:tiles-url\>http:\/\/imageserver.techlib.cz\/$1\/$2\/$3\/$4\/$1$2$3$4$5.jp2\<\/kramerius:tiles-url\>/g ) {
print "$radek\n\n";
print FOXML <$radek>;
Ale asi to tak jednoduché nebude, že? (protože když ten zápis do souboru zapíšu takhle, tak se také nic nezmění)
-
To treba zapisat do suboru - obycajne sa pouziva zapis do ineho suboru, ako mate, aby bola zaloha starej verzie a az nakoniec sa subory nahradia.
A mimochodom, parsovanie XML pomocou regexpu je ZLO, ktore v 90% pripadov funguje len nahodou pre par spravnych vstupov, v 9% pripadov funguje ale nikto to nedokaze zarucit a vlastne ani porozumiet regexpu a v 1% pripadov nefunguje a ani nie je mozne vymysliet vymysliet regexp, s ktorym by to fungovalo.
-
A je nějaká možnost, jak změnu zapsat do aktuálně otevřeného souboru na místo nelezené pomocí toho regulárního výrazu? Mohl bych vás eventuelně poprosit o ukázku kódu? Právě, že bych dost nerad "kopíroval" celé XML do nového souboru, jen proto, abych nahradil jeho malou část...
-
Jaký máš důvod nepoužít sed -i ?
-
A je nějaká možnost, jak změnu zapsat do aktuálně otevřeného souboru na místo nelezené pomocí toho regulárního výrazu? Mohl bych vás eventuelně poprosit o ukázku kódu? Právě, že bych dost nerad "kopíroval" celé XML do nového souboru, jen proto, abych nahradil jeho malou část...
Pokud nepracuješ s databází, tak se prakticky vždy kopíruje (se změnami) celý soubor do nového souboru a ten se následně přejmenuje. Pokud tedy potřebuješ takovou funkčnost, použij databázi.
-
A je nějaká možnost, jak změnu zapsat do aktuálně otevřeného souboru na místo nalezené pomocí toho regulárního výrazu? Mohl bych vás eventuelně poprosit o ukázku kódu? Právě, že bych dost nerad "kopíroval" celé XML do nového souboru, jen proto, abych nahradil jeho malou část...
Jak si představuješ, že to operační systém udělá? Pokud budou původní a nahrazovaný řetězec stejně dlouhé, může jen ten kousek "přepsat přímo na disku". Pokud ale bude jediný byte přebývat/chybět, musí být stejně zapsány VŠECHNY následující byte až do konce souboru. Zde navrhovaný postup čtu: z A, zapisuji do B, hotovo, smažu A, přejmenuji B na A ber jako obvyklý, vhodný, jediný možný.