Como leer línea por línea en un archivo de sólo CR con Perl?
-
26-09-2019 - |
Pregunta
Estoy intentando leer un archivo que sólo tiene CR como delimitador de línea. Estoy utilizando Mac OS X y v.5.8.8 Perl. Este script debe ejecutarse en todas las plataformas, para cada tipo de línea de delimitador (CR, LF, CRLF).
Mi código actual es la siguiente:
open(FILE, "test.txt");
while($record = <FILE>){
print $record;
}
close(TEST);
Esta actualmente imprimir sólo la última línea (o peor). Que esta pasando? Obvisously, me gustaría no convertir el archivo. ¿Es posible?
Solución
Se puede configurar el delimitador utilizando la variable $/
especial:
local $/ = "\r" # CR, use "\r\n" for CRLF or "\n" for LF
my $line = <FILE>;
perldoc perlvar para más información.
Otra solución que funciona con todo tipo de saltos de línea serían sorber todo el archivo a la vez y luego dividirlo en líneas utilizando una expresión regular:
local $/ = undef;
my $content = <FILE>;
my @lines = split /\r\n|\n|\r/, $content;
Usted no debe hacer eso con archivos muy grandes, aunque, como el archivo se lee en la memoria por completo. Tenga en cuenta que el establecimiento $ / hasta el valor indefinido desactiva el delimitador de línea, lo que significa que todo lo que se lee hasta el final del archivo.
Otros consejos
I resolvió un problema más general que podría ser útil aquí:
Cómo analizar gran línea por línea de archivo con cualquier línea de delimitador (CR / CRLF / LF), pero antes desconocida.
'grandes' medios de archivo que no está bien para leer todo el archivo en una variable. Aquí la función 'detectEndOfLine' se pone el nombre de archivo y devuelve o '\ r' o '\ n', todo lo que se utiliza para el final de línea (que buscó '\ r' o '\ n' símbolo char-por-char a partir de la final del archivo).
my $file = "test.txt";
local $/ = detectEndOfLine($file);
open(IN, $file) or die "Can't open file \"$file\" for reading: $!\n";
while(<IN>) {
s/\r\n|\n|\r$//;
print "$_\n";
}
sub detectEndOfLine {
my $file = $_[0];
my $size = -s $file;
print "\"$size\"\n";
open(IN, $file) or die "Can't open file \"$file\" for reading: $!\n";
for(my $i = $size; $i >= 0; --$i) {
seek(IN, $i, 0);
$_ = <IN>;
my $sym = substr($_, 0, 1);
return $sym if( $sym eq "\n" or $sym eq "\r" );
}
return undef;
}