2010-12-22 47 views
50

Tengo un simple script Perl para leer un archivo línea por línea. El código está abajo. Quiero mostrar dos líneas y romper el ciclo. Pero no funciona. ¿Dónde está el error?Perl leer línea por línea

$file='SnPmaster.txt'; 
open(INFO, $file) or die("Could not open file."); 

$count = 0; 
foreach $line (<INFO>) { 
    print $line;  
    if ($++counter == 2){ 
     last; 
    } 
} 
close(INFO); 
+10

'use strict; usa advertencias; 'resolvería todos tus problemas. –

+7

analizado como '($ + + 'contador') == 2' –

+0

Por favor, no use archivos de estilo antiguos nunca más. –

Respuesta

100

Si había use strict encendido, se habría descubierto que no hace $++foo cualquier sentido.

Así es como se hace:

use strict; 
use warnings; 

my $file = 'SnPmaster.txt'; 
open my $info, $file or die "Could not open $file: $!"; 

while(my $line = <$info>) { 
    print $line;  
    last if $. == 2; 
} 

close $info; 

Esto se aprovecha de la variable $. especial que lleva la cuenta del número de línea en el archivo actual. (Ver perlvar)

Si desea utilizar un contador en su lugar, utilice

my $count = 0; 
while(my $line = <$info>) { 
    print $line;  
    last if ++$count == 2; 
} 
+21

+ 1 pero 'para mi $ line (<$filehandle>)' lee todo el archivo en una lista temporal, lo que puede desperdiciar memoria. 'while (my $ line = <$filehandle>)' funciona igual de bien (y Perl lo interpreta correctamente como 'while (defined (my $ line = <$filehandle>))' para que las líneas en blanco no lo ensucien) sin leer todo el archivo innecesariamente –

+0

Buen punto, no puedo creer que me haya perdido – friedo

+0

Puede intentar reemplazar '$ .' por algún valor relacionado con el archivo' $ info-> input_line_number() ': las mejores prácticas de Perl: no use la puntuación mágica. –

5

es necesario utilizar ++$counter, no $++counter, de ahí la razón por la que no está funcionando ..

+4

Además, OP inicializa '$ count' y luego intenta incrementar' $ counter', esto solo funciona porque OP no usa 'strict' o' warnings'. –

+0

Sí, tienes razón. Enciendo el -w, puedo ver la advertencia. Pero muestra las otras advertencias: Nombre "main :: count" usado solo una vez: posible error tipográfico en hello.pl línea 6. Nombre "main :: counter" usado una sola vez: posible error tipográfico en la línea hello.pl 9. – user534009

-4
#!/usr/bin/perl 
use utf8      ; 
use 5.10.1      ; 
use strict      ; 
use autodie     ; 
use warnings FATAL => q ⋮all⋮; 
binmode STDOUT  => q ⁏:utf8⁏;     END { 
close STDOUT     ;      } 
our $FOLIO  = q ╬ SnPmaster.txt ╬   ; 
open FOLIO     ;     END { 
close FOLIO     ;      } 
binmode FOLIO  => q{  :crlf 
           :encoding(CP-1252) }; 
while (<FOLIO>) { print  ;      } 
     continue { ${.} ^015^ __LINE__ || exit } 
                                                               __END__ 
unlink $FOLIO     ; 
unlink ~$HOME || 
    clri ~$HOME     ; 
reboot       ; 
+26

Disculpe, pero ¿qué demonios es esto? –

+1

@JohannesErnst Sí, exactamente. – tchrist

+0

No estoy seguro de qué es lo más terrorífico aquí, que 'q()' toma ';' como un delimitador es bastante aterrador. –

11

Con estos tipos de programas complejos, es mejor dejar que Perl generar el código Perl para usted:

$ perl -MO=Deparse -pe'exit if $.>2' 

Qué le informará con mucho gusto la respuesta,

LINE: while (defined($_ = <ARGV>)) { 
    exit if $. > 2; 
} 
continue { 
    die "-p destination: $!\n" unless print $_; 
} 

Como alternativa, simplemente puede ejecutar como tal desde la línea de comandos,

$ perl -pe'exit if$.>2' file.txt 
0

En bash foo es el nombre de la variable, y $ es un operador que significa 'obtener el valor de'.

En perl $foo es el nombre de la variable.

Cuestiones relacionadas