Newsgroup: it.comp.lang.perl
Titolo: Estrarre una porzione di file delimitata

Rieccomi,
 
	  scusate la menata, ma ho un'altra "sfida" da proporvi.
	  Il problema adesso e' questo... ho un file di questo tipo:
stampa.txt
----------------------
foo foo foo foo foo foo foo foo foo foo foo foo foo 
foo foo foo foo foo foo foo foo foo foo foo foo foo 
foo foo foo foo foo foo foo foo foo foo foo foo foo 
foo foo foo foo foo foo foo foo foo foo foo foo foo 
foo foo foo foo foo foo foo foo foo foo foo foo foo 
*****INIZIO
bar bar bar bar bar bar bar bar bar bar bar bar bar
bar bar bar bar bar bar bar bar bar bar bar bar bar
bar bar bar bar bar bar bar bar bar bar bar bar bar
bar bar bar bar bar bar bar bar bar bar bar bar bar
bar bar bar bar bar bar bar bar bar bar bar bar bar
bar bar bar bar bar bar bar bar bar bar bar bar bar
bar bar bar bar bar bar bar bar bar bar bar bar bar
*****FINE
foo foo foo foo foo foo foo foo foo foo foo foo foo 
foo foo foo foo foo foo foo foo foo foo foo foo foo 
foo foo foo foo foo foo foo foo foo foo foo foo foo 
foo foo foo foo foo foo foo foo foo foo foo foo foo 
foo foo foo foo foo foo foo foo foo foo foo foo foo 
foo foo foo foo foo foo foo foo foo foo foo foo foo 
foo foo foo foo foo foo foo foo foo foo foo foo foo 
foo foo foo foo foo foo foo foo foo foo foo foo foo 
----------------------
	Ho bisogno di estrarre tutto cio' che stra tra *****INIZIO e
	*****FINE.
	Immagino che debba usare una funzione per spostarmi alla linea di
	*****INIZIO e poi leggere tutto il contenuto in un array fino a
	*****FINE, ma non ho idea di che sintassi usare o di quali
	funzioni ci sono a disposizione.
	Buona serata a tutti!
--
Kristian

 
[CUT]
Ma a te interessa imparare il perl o no?
Prova a postare un pò di codice, fai un pò di fatica almeno.
Non è bello dire "Ce l'ho fatta da solo!" ?
Ciao,
-- 
+--------+ ASCII ribbon campaign ( )
|  kral  |  - against HTML email  X 
+--------+              & vCards / \

	funzioni ci sono a disposizione.
A parte il "trucchetto" sopra, le "funzioni" che cerchi possono essere
semplicemente due cicli di lettura: appena incontri "*****INIZIO" esci dal
primo ciclo (istruzione last), che non fa nulla; il secondo stampa quello
che deve stampare finché non incontra "*****FINE", quindi esce.
Ciao.

 foo foo foo foo foo foo foo foo foo foo foo foo foo
foreach (<STDIN>) {
    esci pure se /^*****FINE/;
    metti $_ in @array if $aggiungi;
    $aggiungi è 1 if /^*****INIZIO/;
}
print @array;
Dovrebbe funzionare...
Valerio
-- 
Valerio Granato
http://www.musicoff.com
 - Music Online For Free
La Grande Comunità Online per Musicisti

 Non è bello dire "Ce l'ho fatta da solo!" ?
	Hai ragione... e' solo che in questo caso non sapevo neppure da
	che parte cominciare.
	Il problema che ho presentato precedentemente avevo provato a
	risolverlo da solo, ed avevo anche del codice abbastanza vicino
	alla soluzione. 
	La prossima volta faro' in modo di postare i miei tentativi..
	promesso!
	Grazie per avermi ripreso Kral.
--
Kristian

	che parte cominciare.
Guarda perň che il caso č molto piů semplice del precedente. Lascia stare il
mio esempio (non sei obbligato ad usare la magia nera, se la tua religione
non te lo consente): la cosa poteva essere risolta semplicemente cosě:
    while (<INFILE>) {
      last if (/^\*\*\*\*\*INIZIO$/);
    }
    while (<INFILE>) {
      last if (/^\*\*\*\*\*FINE$/);
      print;
    }
Ciao.

 C'e' qualcosa di esatto?
Vediamo se posso venire io in aiuto di qualcuno adesso :)
Prova con questo:
#!C:\perl\bin\perl.exe  
$uno='a:\La.txt';
$due='c:\0perl\La.txt';
open(INFILE, "<$uno") or die "Non apre uno.xxx";
open(OUTFILE, ">$due") or die "Non apre due.xxx";
    while (<INFILE>) {
      last if (/^\[Ho\]?/);
    }
    while (<INFILE>) {
      last if (/^\[Pioneer\]?/);
      print OUTFILE $riga;
    }
close(INFILE);
close(OUTFILE);
Sinceramente non so perche', ma sembra che la sintassi colorata di
vi/vim segnali che i filehandle debbano essere tutti maiuscoli e di piu'
di una lettera. Ho provato nominandoli come hai fatto tu, e neppure a me
ha funzionato.
Ho inoltre modificato le tue espressioni regolari. Se il tuo file
somiglia a qualcosa del tipo,
	-------
	fkdjsafljdf
	fdsfdsfds
	fdsf
	dsfdsfdsfjlkj ds fds
	[Ho] fjdskl fj
	fjdkfjkj f
	fjdskfjdskl fds
	fj dsklfj dsklafjds
	[Pioneer] jdka jds a
	djskl jd 
	dsaj ksa j
	--------
allora hai bisogno dei caratteri di escape-are "[" e "]" per evitare che
vengano interpretati come delimitatori di classe (wow quanto ho imparato
in un paio di giorni!!). Per di piu' ho cambiato il tuo "$", che credo
voglia dire "fine riga", con "?", che dovrebbe voler dire "fine parola",
sempre che la memoria non m'inganni!
-- 
Kristian

di un file da: [Ho]....fino a: [Pioneer].
All'interno dell'espressione regolare, il carattere ^ vuol dire "inizio", e
il carattere $ vuol dire fine, sicché se quello che cerchi č una riga cosě:
    [Ho]
non potrai mai trovarla con /^Ho$/ perché la riga non comincia con 'H', ma
con '['. Dovrai usare invece /^\[Ho\]$/. Se invece hai usato le parentesi
quadre in modo discorsivo, per racchiudere quello che stai cercando, e non
fanno realmente parte dei dati, come non detto.
Ciao.

m'inganni!
No, il carattere '?' significa "c'è o non c'è" o "una o nessuna occorrenza"
dell'elemento che precede. Per cercare il confine di parola (o di non
parola) si possono usare le asserzioni \b (o \B). In questo caso, però, dato
che ']' è già un carattere di non-parola, non è molto chiaro che cosa si sta
cercando. Se si vuole escludere il caso "[Ho]fjdskl fj", si può usare
/^\[Ho\]\B/.
Ricordo infine che ci sono dei moduli per accedere agli file .ini in stile
Windows, se mai si trattasse di questo.
Ciao.

Sicuramante commetto qualche "cappellata" .
Hai avuto la risposta giusta alla domanda sbagliata, adesso prova a fare la
domanda giusta che vediamo. Prova anche a fare qualche sforzo in piů per
capire il senso di quello che ti viene proposto.
Ciao.

suggerimento che avevi dato a lui!!!
Con appena un piccolissimo, irrisorio sovraprezzo potevi "carpire" anche
qualche spiegazione qui e là, e così capire che la soluzione proposta a lui
non poteva addattarsi al tuo problema. Che, per inciso (spiacente di darti
un'altra delusione) ancora non ho capito quale esattamente sia.
Supponendo che sia "in un flusso di testo organizzato in righe, recuperare
la prima occorrenza di quanto compreso fra i delimitatori 'Nel' e 'Pioneer',
dovunque si trovino sulla riga", si potrebbe tentare qualcosa di simile al
seguente ennesimo prodotto della mia oziosità:
    use English;
    open INFILE, "< input.txt";
    open OUTFILE, "> output.txt";    
    while (defined($riga = <INFILE>)) {
      if ($riga =~ /Nel/) {
          $riga = substr($riga, $LAST_MATCH_START[0]);
          last;
      }
    }
    while (defined($riga)) {
        if ($riga =~ /Pioneer/) {
            print OUTFILE substr($riga, 0, $LAST_MATCH_END[0]), "\n";
            last;
        } else {
            print OUTFILE $riga;
        }
        $riga = <INFILE>;
    }
 
    close OUTFILE;
    close INFILE;
Ciao.