J'essaie d'écrire un script Perl simple qui lit un * .csv, place les lignes du fichier * .csv dans une matrice bidimensionnelle, imprime un élément hors de la matrice et imprime une rangée de la matrice. .
#!/usr/bin/perl use strict; use warnings; open(CSV, $ARGV[0]) || die("Cannot open the $ARGV[0] file: $!"); my @row; my @table; while(<CSV>) { @row = split(/\s*,\s*/, $_); push(@table, @row); } close CSV || die $!; foreach my $element ( @{ $table[0] } ) { print $element, "\n"; } print "$table[0][1]\n";
6 Réponses :
a,b,c d,e,f g,h,i
Vous avez besoin de deux modifications:
@Table code> li>
ol> Donc, votre programme devrait regarder ceci: p> xxx pré> p>
Peut-être que c'est ce que vous voulez réellement:
#!/usr/bin/perl use strict; use warnings; open(CSV, $ARGV[0]) || die("Cannot open the $ARGV[0] file: $!"); my @table; while(<CSV>) { my @row = split(/\s*,\s*/, $_); push(@table, \@row); } close CSV || die $!; foreach my $element ( @{ $table[0] } ) { print $element, "\n"; } print "$table[0][1]\n";
Il serait préférable d'utiliser la forme moderne d'ouverture: ouvert (mon $ CSV, '<', $ argv [0])
Changer puis il imprime ok. p> p>
... Mais la mauvaise chose de @row code> n'est-elle pas créée à l'intérieur de la boucle.
... mais cela pourrait être réparé si vous dites push @table, [@row] code> pour utiliser une référence à une copie de
@row code>.
Vous ne créez pas une matrice bidimensionnelle (un AOA ou «Tableau de tableaux» dans Perl-Parlance). Cette ligne: ajoute les données dans tout en utilisant @row code> à
@Table code>. Vous devez appuyer à la place d'une référence et créer une nouvelle variable à chaque fois via la boucle afin de ne pas pousser la même référence à plusieurs reprises: p>
Split code> est correct pour les fichiers CSV triviaux, il est malheureusement insuffisant pour autre chose. Utilisez un module comme texte :: csv_xs à la place: p>
TRAY-OF-TRAY est la bonne nomenclature. Il n'y a vraiment pas de liste de liste à Perl. (Nom du Perllol Code> Manpage Nonobstant. Soupir.)
@friedo: point pris. J'ai vu lol utilisé plusieurs fois, mais ce n'est pas une excuse pour diffuser des idées fausses. Fixé.
Si vous appelez PUSH avec les arguments de la liste, vous appendez la première liste avec la liste restante dans la mode Stack Wise. Lisez à propos de la poussée à Perldoc . Donc votre appel de Vous avez reçu plusieurs messages qui Appuyez sur une référence de liste à syntaxiquement, vous pouvez également appuyer sur une référence de matrice anonyme dans l'élément scalaire d'une liste pour créer une liste multidimensionnelle. La chose la plus importante à savoir sur les références à Perl est la suivante: 1) Ils sont un scalaire et 2) ils peuvent faire référence à tout ce qui est dans Perl - Code, tableau, hachage, une autre référence. Passez un peu de temps avec le Tutoriel Perl Ref et cela deviendra plus clair. Avec votre code, il suffit d'ajouter Le problème spécifique que vous avez, comment Pour créer et accéder à une liste multidimensionnelle, est également très bien traitée dans Tom Christensen's Tutoriel de Perllol le Des solutions à vos problèmes spécifiques avec votre code sont directement traitées ici. P> Réécrivez votre code avec le code exact de Tom's Exemple en Perllol, il devient: P> pousser (@Table, @row); code> crée une liste plus longue
@Table code>, pas un tableau à deux dimensions.
@row code> comme
\ @ ligne code> créera une liste de lignes, et cela fonctionne en effet. J'ai tendance à le faire un peu différemment. Bien sûr, avec Perl, il y a toujours une autre façon de le faire! P>
[] code> autour de l'élément que vous souhaitez être la 2e dimension de votre liste, donc
push (@Table, @row); code> devrait être
Appuyez sur (@Table, [@row]); code> dans le même sens, vous mettez
[] code> autour de votre scission afin qu'il devienne
poussoir (@ split ( / \ s *, \ s * /, $ _)]]); code> Cela effectuera simultanément la scission et créera une matrice anonyme au résultat. P>
#!/usr/bin/perl
use strict;
use warnings;
my (@row, @table, $n, $rowref);
while(<DATA>) {
chomp;
# regex to separate CSV (use of a cpan module for CSV STRONGLY advised...
@row = /(?:^|,)("(?:[^"]+|"")*"|[^,]*)/g;
for (@row) {
if (s/^"//) { s/"$//; s/""/"/g; }
}
push(@table, [ @row ]); #Note the [ ] around the list
}
# Now the table is created, print it:
my $rowcnt=0;
foreach $rowref (@table) {
print "row $rowcnt:\n";
$rowcnt++;
print " [ @$rowref ], \n";
}
# You can access the table in the classic [i][j] form:
for my $i ( 0 .. $#table ) {
$rowref = $table[$i];
$n = @$rowref - 1;
for my $j ( 0 .. $n ) {
print "element $i, $j of table is $table[$i][$j]\n";
}
}
# You can format it:
for my $i ( 0 .. $#table ) {
print "$table[$i][0] $table[$i][1]\n";
print "$table[$i][2]\n";
print "$table[$i][3], $table[$i][4] $table[$i][5]\n\n";
}
__DATA__
Mac,Doe,120 jefferson st.,Riverside, NJ, 08075
Jack,McGinnis,220 hobo Av.,Phila, PA,09119
"John ""Da Man""",Repici,120 Jefferson St.,Riverside, NJ,08075
Stephen,Tyler,"7452 Terrace ""At the Plaza"" road",SomeTown,SD, 91234
,Blankman,,SomeTown, SD, 00298
"Joan ""Joan, the bone""",Jett,"9th, at Terrace plc",Desert City,CO,00123
+1 pour ne pas gaspiller le temps de tout le monde en omettant
utiliser strict; Utiliser des avertissements; code>.
Vous devriez vraiment éviter 2 argument
Ouvrir code>. Il possède un certain nombre de problèmes qui sont les meilleurs à éviter (pour la discussion, voir cet article de Perlmonks 2001: perlmonks.org /? node_id = 131085 ) Voir ceci pour info sur les poignées lexicales: Stackoverflow.com/questions/613906/...
Voir
Perldoc Perllol CODE>
- Accéder à l'accès et à l'impression