Suche…


Der manuelle Weg

open my $fh, '<', $filename
    or die "Could not open $filename for reading: $!";
my $contents = do { local $/; <$fh> };

Nach dem Öffnen der Datei (read man perlio wenn Sie bestimmte man perlio anstelle von rohen Bytes lesen möchten), liegt der Trick im do Block: <$fh> , das Dateihandle in einem Diamond-Operator, gibt einen einzelnen Datensatz aus der Datei zurück . Die Variable $/ Eingabedatentrenner $/ gibt an, was ein "Datensatz" ist. Standardmäßig ist er auf ein Zeilenvorschubzeichen gesetzt, so dass "Datensatz" "eine einzelne Zeile" bedeutet. Da $/ eine globale Variable ist, führt local zwei Dinge aus: Sie erstellt eine temporäre lokale Kopie von $/ , die am Ende des Blocks verschwindet, und gibt den (Nicht-) Wert undef (den "Wert", den Perl gibt, an zu nicht initialisierten Variablen). Wenn der Eingabedatentrenner diesen (Nicht-) Wert hat, gibt der Diamantoperator die gesamte Datei zurück. (Es betrachtet die gesamte Datei als eine einzige Zeile.)

Mit do können Sie sogar eine Datei manuell öffnen. Zum wiederholten Lesen von Dateien

sub readfile { do { local(@ARGV,$/) = $_[0]; <> } }
my $content = readfile($filename);

kann verwendet werden. Hier wird eine andere globale Variable ( @ARGV ) lokalisiert, um den gleichen Prozess zu simulieren, der beim Starten eines Perl-Skripts mit Parametern verwendet wird. $/ ist immer noch undef , da das Array davor alle eingehenden Argumente "frisst". Als Nächstes liefert der Diamantoperator <> erneut einen durch $/ (die gesamte Datei) definierten Datensatz und kehrt vom do Block zurück, der wiederum vom Sub-Block zurückkehrt.

Das Sub hat keine explizite Fehlerbehandlung, was eine schlechte Praxis ist! Wenn beim Lesen der Datei ein Fehler auftritt, erhalten Sie undef als Rückgabewert, im Gegensatz zu einer leeren Zeichenfolge aus einer leeren Datei.

Ein weiterer Nachteil des letzten Codes ist die Tatsache, dass Sie PerlIO nicht für andere Dateikodierungen verwenden können - Sie erhalten immer rohe Bytes.

Pfad :: Tiny

Die Verwendung des Idioms von The Manual Way in einem Skript wird bald langweilig, so dass Sie ein Modul ausprobieren möchten.

use Path::Tiny;
my $contents = path($filename)->slurp;

Sie können eine binmode Option übergeben, wenn Sie die Kontrolle über binmode , Zeilenenden usw. benötigen. Siehe man perlio :

my $contents = path($filename)->slurp( {binmode => ":encoding(UTF-8)"} );

Path::Tiny hat auch viele andere Funktionen für den Umgang mit Dateien, so dass es eine gute Wahl sein kann.

Datei :: Slurper

Dies ist ein minimalistisches Modul, das Dateien nur in Variablen verschlüsselt, sonst nichts.

use File::Slurper 'read_text';
my $contents = read_text($filename);

read_text() benötigt zwei optionale Parameter, um die read_text() anzugeben und anzugeben, ob Zeilenenden zwischen den unixish LF- oder DOSish-CRLF-Standards übersetzt werden sollen:

my $contents = read_text($filename, 'UTF-8', 1);

Datei :: Slurp

Verwenden Sie es nicht. Obwohl es schon lange existiert und immer noch das Modul ist, das die meisten Programmierer vorschlagen werden, ist es defekt und wahrscheinlich nicht behoben .

Slurping einer Datei in eine Array-Variable

open(my $fh, '<', "/some/path") or die $!;
my @ary = <$fh>;

Bei der Auswertung im Listenkontext gibt der Diamantoperator eine Liste zurück, die aus allen Zeilen in der Datei besteht (in diesem Fall wird das Ergebnis einem Array mit Listenzusammenhang zugewiesen). Der Leitungsabschluss wird beibehalten und kann durch chomping entfernt werden:

chomp(@ary); #removes line terminators from all the array elements.

Slurp-Datei in einem Liner

Das Eingabesatz-Trennzeichen kann mit dem Schalter -0 werden ( Null , nicht Großbuchstabe O ). Als Wert wird eine Oktal- oder Hexadezimalzahl verwendet. Jeder Wert von 0400 oder höher führt dazu, dass Perl Dateien 0777 , der für diesen Zweck verwendete Wert ist jedoch 0777 .

perl -0777 -e 'my $file = <>; print length($file)' input.txt

Wenn Sie die Option -n angeben, liest Perl jede Zeile (in unserem Fall - die gesamte Datei) automatisch in die Variable $_ .

perl -0777 -ne 'print length($_)' input.txt


Modified text is an extract of the original Stack Overflow Documentation
Lizenziert unter CC BY-SA 3.0
Nicht angeschlossen an Stack Overflow