Newsgroup: it.comp.lang.perl
Titolo: aprire e modificare tutti i files di una cartella

Ciao a tutti! Scusate se posto nuovamente per domande forse niubbe!
Ho scritto uno scriptino che mi modifica a mio piacere un file csv, eccolo:
======
#!/usr/bin/perl
open (INF, "< /home/marco/gtap/qotes.csv");
open (OUF, ">> /home/marco/gtap/qotesmod.csv");
#si tolgono i campi che non interessano
$datiinentrata = <INF>;
@datiinuscita = split (/;/, $datiinentrata);
#si scrive il file con i soli campi necesssari
print OUF $datiinuscita[0];
print OUF ";";
print OUF $datiinuscita[1];
print OUF ";";
print OUF $datiinuscita[5];
print OUF ";";
print OUF $datiinuscita[6];
print OUF ";";
print OUF $datiinuscita[7];
print OUF ";";
print OUF $datiinuscita[8];
close INF;
close OUF;
#si tolgono i punti e virgola e si sostituiscono con tabulazioni per una
#elaborazione da parte di mysql
open (INF, "< /home/marco/gtap/qotesmod.csv");
open (OUF, "> /home/marco/gtap/mysqldata.csv");
while ($riga=<INF>)
{
$riga =~ s/;/ /g;
#si scrive il file in formato leggibile da mysql
print OUF $riga;
}
close INF;
close OUF;
======
Vorrei fargli processare non il singolo file qotes.csv, ma una intera
directory contenente files csv. Come posso fare?
Ho penato al modulo File::Find, ed ad una struttura for, ma vorrei dei
consigli da voi esperti su come implementarli!
Grazie dell'aiuto che mi fornirete, e mi scuso se vi rubo del tempo...
-- 
Marco Siviero
Usin' Slackware Linux 10.1 (2.6.10 kernel) on a Compaq Presario 2175EU
notebook (AMD Athlon XP-M 2800+ CPU)
Linux proud user #373650
www.antidigitaldivide.org


Tradotto in linguaggio umano, devi prendere dei file CSV, estrarre i campi 0,1, 5- 8
e trasformare i separatori in tab.
In Perl, io scrivo cosi':
$ find nomedirectory -type f -name "*.csv"  \
   -exec perl -F";" -lane 'print join"\t",@F[0,1,5..8]' {} \; > nomefile_con_tab.txt
Nota: find e' un comando reperibile in ogni Unix
parametri di Perl:
  -n legge il file passato sulla linea di comando
  -a esegue uno split automatico
  -F dice su quale pattern fare lo split
  -l toglie il "\n" in input, e lo inserisce in output
  -e esegue la stringa seguente come uno script
Dentro lo script, @F e' l'array che ha gli elementi prodotti dallo split automatico
@F[0,1,5..8] e uno "slice" che prende dall'array solo gli elementi indicati
{} e' il nome del file passato da "find".
Come vedi, la descrizione e' piu' lunga dell'eseguibile!
Il risultato e' che hai un file "nomefile_con_tab.txt"
che contiene le righe di tutti i csv, con i campi separati da tab.
Ciao
gmax
-- 
   ____ ____  _____ _   _
  / _  |    \(____ ( \ / )
( (_| | | | / ___ |) X (
  \___ |_|_|_\_____(_/ \_)
(_____|
MySQL Certified Professional
Sapere, saper fare, fare, far sapere
http://gmax.oltrelinux.com

 che contiene le righe di tutti i csv, con i campi separati da tab.
Mi sono spiegato male!
Io voglio un file in uscita (con i soli campi 0,1, 5-8 coi separatori
trasformati in tab) per ogni file ".csv" in entrata.
Questo perchè vorrei importare i dati di ciascun file *.csv in una tabella
distinta di mysql!
Ogni file csv contiene chiusura massimo minimo apertura e volume di un
titolo azionario, e dedico una tabella di mysql a ciascun titolo azionario.
Hai idee su come prendere dei file CSV, estrarre i campi 0,1, 5-8
e trasformare i separatori in tab, craendo un file in uscita per ogni *.csv
in entrata?


 in entrata?
Apri la directory con readdir 
(
http://perldoc.perl.org/functions/readdir.html
), apri singolarmente
ogni file e lo processi come credi opportuno.
  Raffaello

consigli da voi esperti su come implementarli!
Prova con:
my @csvfiles = <*.csv>;
foreach $filecsv (@csvfiles){
# in $filecsv hai i nomi dei files
}
'bye

 }
Sono riuscito a risolvere tutto grazie al tuo consiglio, solo che i dati in
uscita vengono raccolti in un solo file (sostituendo nel listato
sottoriporatato a "...open (OUF, ">> /home/marco/gtap/csvmod/$csv")", "open
(OUF, ">> /home/marco/gtap/csvmod/FILEDIUSCITA")).
Io voglio che ad un file CSV in entrata corrisponda ad un file in uscita,
non che i dati in uscita vengano raggruppati in un solo file (come con la
modifica riportata sopra). Ho pensato a qualcosa come questo, ma
chiaramente non funziona:
======
#!/usr/bin/perl
@csv = </home/marco/gtap/csv/*.csv>;
foreach $csv (@csv)
{
 open (INF, "< $csv") && open (OUF, ">> /home/marco/gtap/csvmod/$csv");
 $datiinentrata = <INF>;
 @datiinuscita = split (/;/, $datiinentrata);
 print OUF $datiinuscita [0];
 print OUF " ";
 print OUF $datiinuscita [7];
 close INF;
 close OUF;
}
======
Avete dei consigli per sistemare questo script?
Vi ringrazio ancora.


 ogni file e lo processi come credi opportuno.
Grazie ci ho studiato su un po', ma la strada proposta da Agostino mi sembra
più agevole!


 #!/usr/bin/perl
use strict;
my @csv = </home/marco/gtap/csv/*.csv>;
my %output;
  for my $csv (@csv)
  {
  open (INF, "< $csv") && open (OUF, ">> /home/marco/gtap/csvmod/$csv");
  my $datiinentrata = <INF>;
  my @datiinuscita = split (/;/, $datiinentrata);
##> print OUF $datiinuscita [0];
##> print OUF " ";
##> print OUF $datiinuscita [7];
  $output{$csv} .= $datiinuscita[0]." ".$datiinuscita [7];
  close INF;
##> close OUF;
  }
for my $k(keys %output) {
 	my $filename = $k.".output";
 	open (OUF,"> $filename");
 	print OUF $output{$k};
 	close OUF;


Raffaello Galli wrote:
Grazie per lo script. Purtroppo non funziona o forse sono io che sono brocco
e non lo so far funzionare... 
Mi dice:
Global symbol "@datiinuscita" requires explicit package name at 
csv.pl
 line
10.
Global symbol "@datiinuscita" requires explicit package name at 
csv.pl
 line
10.
se lo lancio...
Inoltre potresti spiegarmi a grandi linee le procedure che hai utilizzato, o
almeno dirmi dove le posso trovare spiegate? Ti ringrazio...
======
#!/usr/bin/perl
use strict;
my @csv = </home/marco/gtap/csv/*.csv>;
my %output;
for my $csv (@csv)
{
open (INF, "< $csv") && open (OUF, ">> /home/marco/gtap/csvmod/$csv");
my $datiinentrata = <INF>;
my $datiinuscita = split (/;/, $datiinentrata);
$output{$csv} .= $datiinuscita[0]." ".$datiinuscita[7];
close INF;
}
for my $k(keys %output)
{
my $filename = $k.".output";
open (OUF,"> $filename");
print OUF $output{$k};
close OUF;
}
=======


 my $datiinentrata = <INF>;
# SBAGLIATO#> my $datiinuscita = split (/;/, $datiinentrata);
# GIUSTO:#
my @datiinuscita = split (/;/, $datiinentrata);


 i diversi testi che vuoi ottenere alla fine.
Grazie! ora mi leggo la documentazione al riguardo! Scusate, ma sono stra
niubbo nella programmazione!


 niubbo nella programmazione!
Facciamo cosi': tu mi insegni Linux e io ti insegno il Perl. ;)
  Raffaello

Raffaello Galli wrote:

Guarda che non sono un genio anche in quel campo ho solo 9 mesi di
esperienza!
Cmq per installare il pinguino sul pc di casa ti posso dare una mano, come
tutta la community linux!
