Perl Language
Den Inhalt einer Datei in eine Variable einlesen
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