2011-09-23 11 views
5

Ho uno script perl che analizza un file di testo e lo suddivide per riga in un array. Funziona bene quando ogni riga è terminata da LF ma quando terminano con CR il mio script non viene gestito correttamente. Come posso modificare questa linea per risolvere questoCR vs LF perl parsing

my @allLines = split(/^/, $entireFile); 

edit: Il mio file ha una miscela di linee sia con fine LF o finale CR semplicemente crolla tutte le righe quando la sua termina con CR

risposta

11

Perl in grado di gestire sia CRLF e LF line-terminazioni con il built-in :crlfPerlIO strato:

open(my $in, '<:crlf', $filename); 

convertirà automaticamente le terminazioni di linea CRLF in LF e lascerà le terminazioni di linea LF invariate. Ma i file solo CR sono fuori gioco. Se si sa che il file utilizza solo CR, è possibile impostare $/ su "\r" e leggerà riga per riga (ma non cambierà CR in LF).

Se si devono gestire file con terminazioni di linea sconosciute (o anche terminazioni di linea miste in un singolo file), è possibile installare il modulo PerlIO::eol. Allora si può dire:

open(my $in, '<:raw:eol(LF)', $filename); 

e sarà automaticamente convertito CR, CRLF, o fine riga LF in LF durante la lettura del file.

Un'altra opzione è quella di impostare $/ su undef, che leggerà l'intero file in un unico slurp. Quindi dividerlo su /\r\n?|\n/. Ma ciò presuppone che il file sia abbastanza piccolo da adattarsi alla memoria.

+0

Supporta tutto ciò che '\ R' corrisponde? – tchrist

+0

@tchrist, intendi PerlIO :: eol? È XS, e non ho esaminato da vicino il codice, ma penso che gestisca solo le terminazioni di linea CR, LF e CRLF, ma questo copre ogni file che abbia mai visto. – cjm

0

E ' dividerà automaticamente l'input in righe se si legge con <>, ma è necessario cambiare $/ in \r.

$/ è il "separatore del record di input". vedi perldoc perlvar per i dettagli.

Non c'è alcun modo per cambiare ciò che un'espressione regolare considera il fine linea - è sempre una nuova riga.

+0

Supponendo che il file abbia terminazioni di riga di Windows, non cambierebbe $/in \ r \ n? Al momento non ho una macchina Windows attiva, quindi non posso provarla. – Kenny

+1

@Kenny, in Windows, CRLF viene normalmente convertito in LF in lettura, quindi il valore predefinito $/= "\ n" è accettabile e impostarlo su \ r \ n causerebbe problemi. Probabilmente ha a che fare con un file Windows diverso da Windows. – ikegami

1

Si può probabilmente solo di gestire le diverse fine riga quando si fa il split, ad esempio:

my @allLines = split(/\r\n|\r|\n/, $entireFile); 
+3

\ R è utile per questo ora.:) –

+0

Bello :) Non lo sapevo, grazie. –

5

Se si è mescolato fine riga, è possibile li normalizzare abbinando una linea generalizzata chiusura

use v5.10; 

$entireFile =~ s/\R/\n/g; 

è anche possibile aprire un filehandle su una stringa e leggere le linee, proprio come si farebbe da un file:

open my $fh, '<', \ $entireFile; 
my @lines = <$fh>; 
close $fh; 

È anche possibile aprire la stringa con layers that cjm shows.

Problemi correlati