Zoeken…


De handmatige manier

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

Na het openen van het bestand (lees man perlio als je specifieke bestandscoderingen wilt lezen in plaats van onbewerkte bytes), zit de truc in het do blok: <$fh> , de bestandsingang in een diamantoperator, retourneert een enkel record uit het bestand . De "input record separator" variabele $/ specificeert wat een "record" is - standaard staat deze op een nieuweteken, dus "een record" betekent "een enkele regel". Omdat $/ een globale variabele is, doet local twee dingen: het maakt een tijdelijke lokale kopie van $/ die aan het einde van het blok verdwijnt en geeft het de (niet-) waarde undef (de "waarde" die Perl geeft naar niet-geïnitialiseerde variabelen). Wanneer het invoerrecordscheidingsteken die (niet-) waarde heeft, retourneert de diamantoperator het volledige bestand. (Het beschouwt het hele bestand als één regel.)

Met do kunt u zelfs handmatig een bestand openen. Voor het herhaaldelijk lezen van bestanden,

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

kan worden gebruikt. Hier wordt een andere globale variabele ( @ARGV ) gelokaliseerd om hetzelfde proces te simuleren dat wordt gebruikt bij het starten van een perl-script met parameters. $/ is nog steeds niet undef , omdat de array ervoor alle inkomende argumenten "opeet". Vervolgens levert de diamantoperator <> opnieuw één record gedefinieerd door $/ (het hele bestand) en keert terug van het do blok, dat op zijn beurt terugkeert van de sub.

De sub heeft geen expliciete foutafhandeling, wat een slechte gewoonte is! Als er een fout optreedt tijdens het lezen van het bestand, ontvangt u undef als retourwaarde, in tegenstelling tot een lege tekenreeks uit een leeg bestand.

Een ander nadeel van de laatste code is het feit dat u PerlIO niet kunt gebruiken voor verschillende bestandscoderingen - u krijgt altijd onbewerkte bytes.

Path :: Tiny

Het idioom van The Manual Way meerdere keren gebruiken in een script wordt al snel vervelend, dus misschien wilt u een module proberen.

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

U kunt een binmode optie doorgeven als u controle nodig hebt over bestandscoderingen, regeleinden, enz. - zie man perlio :

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

Path::Tiny ook veel andere functies voor het omgaan met bestanden, dus het kan een goede keuze zijn.

File :: Slurper

Dit is een minimalistische module die bestanden alleen in variabelen slurpt, niets anders.

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

read_text() neemt twee optionele parameters om de bestandscodering op te geven en of regeleinden moeten worden vertaald tussen de Unixish LF of DOSish CRLF-standaarden:

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

File :: Slurp

Gebruik het niet. Hoewel het al lang bestaat en nog steeds de module is die de meeste programmeurs zullen voorstellen, is het stuk en zal het waarschijnlijk niet worden opgelost .

Een bestand slurpen tot een matrixvariabele

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

Wanneer geëvalueerd in lijstcontext, retourneert de diamantoperator een lijst die bestaat uit alle regels in het bestand (in dit geval het resultaat toewijzen aan een contextcontext van een arraylevering). De lijnafsluiter blijft behouden en kan worden verwijderd door chomping:

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

Slurp-bestand in één voering

Input record separator kan worden gespecificeerd met -0 schakelaar ( nul , geen hoofdletter O ). Het heeft een octaal of hexadecimaal getal als waarde. Elke waarde 0400 of hoger zorgt ervoor dat Perl bestanden slurpt, maar volgens afspraak is de waarde die voor dit doel wordt gebruikt 0777 .

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

Om verder te gaan met minimalisme, geeft het opgeven van de schakelaar -n dat Perl automatisch elke regel (in ons geval het hele bestand) in variabele $_ leest.

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


Modified text is an extract of the original Stack Overflow Documentation
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow