web-dev-qa-db-fra.com

La bonne façon de lire un fichier de données dans un tableau

J'ai un fichier de données, chaque ligne ayant un numéro, comme

10
20
30
40

Comment lire ce fichier et stocker les données dans un tableau?

Afin que je puisse effectuer certaines opérations sur ce tableau.

28
user297850

La simple lecture du fichier dans un tableau, une ligne par élément, est triviale:

open my $handle, '<', $path_to_file;
chomp(my @lines = <$handle>);
close $handle;

Maintenant, les lignes du fichier sont dans le tableau @lines.

Si vous voulez vous assurer qu'il y a une gestion des erreurs pour open et close, faites quelque chose comme ça (dans la section ci-dessous, nous ouvrez le fichier en mode UTF-8 =, aussi):

my $handle;
unless (open $handle, "<:encoding(utf8)", $path_to_file) {
   print STDERR "Could not open file '$path_to_file': $!\n";
   # we return 'undefined', we could also 'die' or 'croak'
   return undef
}
chomp(my @lines = <$handle>);
unless (close $handle) {
   # what does it mean if close yields an error and you are just reading?
   print STDERR "Don't care error while closing '$path_to_file': $!\n";
} 
75
Sean

Il existe la méthode la plus simple, en utilisant File::Slurp module:

use File::Slurp;
my @lines = read_file("filename", chomp => 1); # will chomp() each line

Si vous avez besoin d'une validation pour chaque ligne, vous pouvez utiliser grep devant read_file.

Par exemple, filtrez les lignes qui ne contiennent que des entiers:

my @lines = grep { /^\d+$/ } read_file("filename", chomp => 1);
11
Taras

J'aime...

@data = `cat /var/tmp/somefile`;

Ce n'est pas aussi glamour que les autres, mais ça marche tout de même. Et...

$todays_data = '/var/tmp/somefile' ;
open INFILE, "$todays_data" ; 
@data = <INFILE> ; 
close INFILE ;

À votre santé.

10
Eric

Tie::File est ce dont vous avez besoin:

Synopsis

# This file documents Tie::File version 0.98
use Tie::File;

tie @array, 'Tie::File', 'filename' or die ...;

$array[13] = 'blah';     # line 13 of the file is now 'blah'
print $array[42];        # display line 42 of the file

$n_recs = @array;        # how many records are in the file?
$#array -= 2;            # chop two records off the end


for (@array) {
  s/Perl/Perl/g;         # Replace Perl with Perl everywhere in the file
}

# These are just like regular Push, pop, unshift, shift, and splice
# Except that they modify the file in the way you would expect

Push @array, new recs...;
my $r1 = pop @array;
unshift @array, new recs...;
my $r2 = shift @array;
@old_recs = splice @array, 3, 7, new recs...;

untie @array;            # all finished
1
Zaid
open AAAA,"/filepath/filename.txt";
my @array = <AAAA>; # read the file into an array of lines
close AAAA;
1
LeoFS

Cela dépend de la taille du fichier! Les solutions ci-dessus ont tendance à utiliser des raccourcis pratiques pour copier l'intégralité du fichier en mémoire, ce qui fonctionnera dans de nombreux cas.

Pour les très gros fichiers, vous devrez peut-être utiliser une conception de diffusion en continu où lire le fichier par ligne ou en mandrins, traiter les morceaux, puis les jeter de la mémoire.

Voir la réponse sur lecture ligne par ligne avec Perl si c'est ce dont vous avez besoin.

0
Mark Stosberg