Newsgroup: it.comp.lang.perl
Titolo: forse dico una bestialità... ma si può fare? (regexp)

Salve, è possibile fare un qualcosa di questo tipo?
    ($testo =~ s/TABLESPACE "(\w+)/TABLESPACE "PIPPO/) if $1='PLUTO';
(in altre parole, nel testo voglio sostituire TABLESPACE PLUTO per
TABLESPACE PIPPO).
Capisco che mi dia errore, ma si può fare un qualcosa di questo tipo con una
sola istruzione? (l'ho risolto con un if ma volevo fare qualcosa di più
elegante)...
grazie,
Paulus
http://spazioweb.inwind.it/it_informatica
--------------------------------
Inviato via 
http://usenet.libero.it

 TABLESPACE PIPPO).
Si... le "altre parole" sono molto piů chiare :-)
    $testo = 'bla bla bla TABLESPACE PLUTO bla bla bla';
    $testo =~ s/TABLESPACE PLUTO/TABLESPACE PIPPO/;
    print $testo;

Salve, ho due domande sulle espressioni regolari ... vabbe', ne ho tante ma
mi limito a 2 :)
1) è possibile fare un qualcosa di questo tipo?
    ($testo =~ s/TABLESPACE "(\w+)/TABLESPACE "PIPPO/) if $1='PLUTO';
(in altre parole, nel testo voglio sostituire TABLESPACE PLUTO per
TABLESPACE PIPPO).
Capisco che mi dia errore, ma si può fare un qualcosa di questo tipo con una
sola istruzione? (l'ho risolto con un if ma volevo fare qualcosa di più
elegante)...
2) lavorando con un file di script di oracle di questo tipo:
CREATE TABLE "PINCO"."TABELLA1" ......................
....... .INITIAL 10274 .....................
CREATE INDEX "PLUTO"."INDICE1" .........................
............... INITIAL 2222 ..............................
io vorrei un output di questo tipo:
TABLE TABELLA1 10274
INDEX INDICE1 2222
e ci sono riuscito (più o meno, perché non mi scrive tutto sulla stessa riga
ma mi piace perché breve) con questo blocco in loop:
    ($tipo,$tabella) =($testo=~ /CREATE (\w+) "\w+"\."(\w+)/);
    ($extent) = ($testo =~ /INITIAL (\w+)/);
    print "$tipo\t$tabella\t$extent\n" if ($tabella) || ($extent);
il problema è che se ho più righe con INITIAL prima di un altro CREATE mi
scrive il numero associato a ogni INITIAL trovato.
ho risolto ponendo $tabella=undef in questo modo:
    $testo=~ /CREATE (\w+) "\w+"\."(\w+)/;
    if ($2)
       { $tabella=$2;
         $tipo = $1};
    ($extent) = ($testo =~ /INITIAL (\w+)/);
    $scrivi = $testo."\n";
    if (($tabella) && ($extent))
       {print "$tipo\t$tabella\t$extent\n";
       $tabella=undef;}
ma non mi convince del tutto... c'è un modo migliore per fare questo?
grazie e scusate se chiedo spesso, ma sono circondato da "microsofniani" !!!
:-P


 $testo =~ s/TABLESPACE PLUTO/TABLESPACE PIPPO/;
si, vedo che ho postato molto male... il fatto è che volevo usare $1 per
confrontarlo con una variabile ARG[..] ma per semplificare ho scritto il
valore direttamente...
scusa e grazie per la risposta,


 scusa e grazie per la risposta,
hmmm... guarda che puoi usare $ARG[n] anche nella RE.
$ARG[0] = 'PLUTO';
$testo = 'bla bla bla TABLESPACE PLUTO bla bla bla';
$testo =~ s/TABLESPACE $ARG[0]/TABLESPACE PIPPO/;
print $testo;
Spiega meglio che magari non ho ancora capito.
Domizio

ma non mi convince del tutto... c'è un modo migliore per fare questo?
Se il documento che devi analizzare e` un pelino complesso, devi costruirti
un pelino di parser. Un pelino di traccia (dico *traccia*) potrebbe essere
questo:
while (<DATA>) {
    while (/^create\s+(\w+)\s+"\w+"\."(\w+)/i) {
        $tipo = $1;
        $tabella = $2;
        $extent = &extent;
        print $tipo, "\t", $tabella, "\t", $extent, "\n";
    }
}
sub extent {
    while (<DATA>) {
        if (/initial\s+(\w+)/i) {
            return $1;
        }
        if (/^create/i) {
            last;
        }
    }
}
__END__
CREATE TABLE "PINCO"."TABELLA1" ......................
....... .INITIAL 10274 .....................
CREATE INDEX "PLUTO"."INDICE1" .........................
............... INITIAL 2222 ..............................
CREATE TABLE "PANCO"."TABELLA2" ......................
CREATE TABLE "PONCO"."TABELLA3" ......................
Quanto sopra costituisce naturalmente solo una *traccia*. Per completarlo
bisogna conoscere con precisione la struttura del file prodotto da Oracle.
(Il quale Oracle, per inciso, mi pare strano che non ti permetta gia` di suo
di costruire un report come lo vuoi tu, ma tant'e`, saprai tu).
Le ultime due righe nei dati (e la conseguente maggiore complessita` nella
*traccia* di parser che ho scritto) le ho aggiunte per l'appunto perche'
senz'altro c'e` qualcosa che non ci hai detto. Vedi tu.
Ciao.
P.S. Mi sembra che il codice debba terminare per forza, ma non mi riesce in
questo momento di raggiungere una certezza matematica al riguardo.
D'altronde e` solo una traccia.
P.P.S. Non ricordo se ho gia` detto che si tratta solo di una *traccia* di
parser.

 wrote in message
news:3oempu4ovurck2o1t...@4ax.com...

... e però dai.... scusa, però per correttezza dovresti dire che quello che hai
scritto è solo una TRACCIA di parser, altrimenti poi la gente lo prende sul
serio!
:-))))))
ciao
dd

 parser.
d'altronde, anche la mia era una *traccia* di post :-P
Grazie!


 :-))))))
Veramente, si tratta di una *traccia* di un *pelino* di parser !!!
:))))))))


 Spiega meglio che magari non ho ancora capito.
Hai capito bene, hai capito... ero io che non avevo ancora capito :-))))))
Grazie mille !


su un altro server di datawarehouse).
Si', avevo capito che si trattava di un compito amministrativo. Database
come InterBase (e, senz'altro, anche Oracle, anzi *soprattutto* Oracle)
hanno appunto delle utilita' per fare questo genere di cose (metareport
sulla struttura del database, log delle transazioni, ecc.). Immaginavo che
ci si potesse arrivare da li'. Evidentemente, se stai cercando di farlo da
perl, non e' cosi'.
Ciao.

a capire cosa cavolo fa /i e last :))))
Provo a spiegare un po'.
Se il documento e' prodotto automaticamente da Oracle, sara' scritto sempre
uguale, sicche' si puo' benissimo cercare "CREATE" e "INITIAL". In sql (si
tratta di un qualche dialetto sql, no?), pero', non c'e' distinzione tra
maiuscole e minuscole, quindi, dal momento anche che costa assai poco,
tanto vale non correre rischi e cercare in modo indipendente dal caso
("create", "Create", "CReAte", e cosi'  via). /i fa appunto questo (I-gnora
il caso dei caratteri).
"last" vuol dire semplicemente "basta", "abbiamo finito", "usciamo di qui":
termina il ciclo (nel caso specifico, forse era piu' corretto metterci un
altro return).
Per il resto, e' la solita idea di implementare un "automa a stati": appena
incontri un "create", passi in un altro stato, in cui ti aspetti un
"initial". Appena lo incontri (o sei sicuro che non lo incontrerai piu')
ritorni a cercare il "create".
La cosa che non ho capito e' se un "initial" DEVE esserci per forza. Mi
sembra ragionevole ipotizzare che possa anche non esserci, per cui non
posso lasciare l'intercettazione di un "initial" come unica strada per
uscire da questo stato (rischio di non uscire mai). L'unico modo sicuro,
per quello che ne so (oltre al termine dell'input), resta l'intercettazione
di un nuovo "create".
Questo e' abbastanza seccante, perche' e' difficile farlo senza ripetere
l'analisi dell'input (la condizione di uscita da uno stato e' uguale alla
condizione di entrata del primo). Di fatto, nel codice che ho postato (che
e' giusto una *traccia*), non ci ho neanche provato: all'uscita dallo stato
"extent", si ritorna allo stato principale, e viene ripetuta l'analisi
sulla stessa riga del file in input.
(In realta', ci sarebbe un modo "semplice" per evitare la doppia analisi:
basta non farsi scrupoli e saltare nel mezzo di un ciclo con un goto.
Pero', via, non sta bene; son cose che non si fanno.)
Questo, piu' o meno, tutto. Se hai bisogno di altri chiarimenti, comunque,
chiedi.
Ciao.

 di un nuovo "create".
si, c'è sicuramente un INITIAL dopo il CREATE... il problema è che oracle
mette un sacco di ALTER TABLE con INITIAL in mezzo, ma che hanno sempre lo
stesso valore che ha INITIAL nel CREATE...
Forse se ti *racconto* il procedimento mi spiego meglio:
con oracle fai un export dei dati, dopo fai un importazione di quel file ma
con un opzione nella quale le dici *non mi dare i dati ma solo le
definizioni degli oggetti esportati* dentro a un file di testo (in quanto
l'export creato ti può anche creare le tabelle se non ci sono, per forza
include anche una parte con gli script di creazione)...
questo file di testo è sempre uguale, scritto interamente in maiuscolo e
contiene tutti i CREATE e ALTER delle tabelle, degli indici, dei vincoli,
dei permessi, delle sequenze, ecc., necessari a ricreare la stessa
situazione che esisteva nel DB al momento dell'esportazione.
da li in poi ho presso quel file e cominciato a fare casini con perl... e a
rompervi con le domande :))
grazie delle spiegazioni,


mezzo, ma che hanno sempre lo stesso valore che ha INITIAL nel CREATE...
Questo non e' un problema, nel senso che il codice cattura comunque solo il
primo INITIAL dopo un CREATE, e ignora tutto il resto. Se serve ottenere
informazioni anche riguardo agli ALTER, basta aggiungere una condizione nel
ciclo principale, ed un altro stato (un'altra sub) per trattare il caso.
Ciao.