Thread Zufallsfunktion im Script (12 answers)
Opened by Compined at 2011-10-11 00:18

payx
 2011-10-11 10:50
#153058 #153058
User since
2006-05-04
564 Artikel
BenutzerIn

user image
Hallo,

angenommen, die Textdatei sei zu groß, um komplett in den Arbeitsspeicher geladen zu werden, wie geht man am besten vor?

Mein Versuch:
Code (perl): (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#!/usr/bin/perl
use strict;
use warnings;

my $file = 'lwall-quotes.txt'; # http://www.cpan.org/misc/lwall-quotes.txt.gz
my $recSep = "%%$/"; # input record separator in dieser Datei

print zufallsEintrag($file, $recSep);

###############################################################################

sub zufallsEintrag {
    $file = shift;
    local $/ = (shift or $/);

    open my $txtFH, "<", $file or die $!;

    my $entryCnt;

    $entryCnt++ while <$txtFH>;

    my $selEntry = int(rand($entryCnt))+1;

    my $entry;

    seek $txtFH,0,0; # wieder an den Anfang
    $.=0; # wird mit seek nicht auf 0 zurückgesetzt

    while ($entry = <$txtFH>) {
        last if $. == $selEntry;
    }
    
    close $txtFH or die $!;
    
    chomp($entry);
    return $entry;
}


Mal angenommen, rand sei zufällig genug.

perlfaq5 empfiehlt zur Ermittlung der Zeilenzahl, die newlines (bzw. hier wohl $/?) zu zählen. Ich weiß nicht ob oder warum das besser wäre als dieser Ansatz hier.

Grüße
payx

PS: Statt Zeile 27-31
Code (perl): (dl )
1
2
3
4
5
    $.=0; # wird mit seek nicht auf 0 zurückgesetzt
    
    while ($entry = <$txtFH>) {
        last if $. == $selEntry;
    }
ginge eigentlich auch
Code (perl): (dl )
1
2
3
    for (1..$selEntry) {
        $entry = <$txtFH>;
    }


Editiert von payx: PS

Editiert von payx: in Zeile 16 local ergänzt, wenn schon sub, so war's gedacht.
Last edited: 2011-10-11 14:20:03 +0200 (CEST)

View full thread Zufallsfunktion im Script