Thread (re)open Textdatei (6 answers)
Opened by toldap at 2010-04-06 17:07

topeg
 2010-04-08 01:43
#135826 #135826
User since
2006-07-10
2611 Artikel
BenutzerIn

user image
Ganz davon ab, dass man so einen Schalter einfacher machen kann:
Code (perl): (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#!/usr/bin/perl
use strict;
use warnings;
my $active=10;

while (1)
{
        
  if ($active)
  {
    print "Active\n";
    $active--;
  }
  else
  {
    print "Inactive\n";
    last();
  }
}


Aber so wie du es angefangen hast funktioniert das nicht, weil Perl die Datei puffert, wenn der Inhalt die Größe des Puffers unterschreitet, dann wird nicht aus der Datei gelesen, und der Puffer ist nur durch die Speichergröße deines Computers begrenzt.
Das würde Klappen wenn du auch über Perl schreibst, dann bekommt das Perl mit wenn du den das selbe Handle nutzt. Weiterhin reicht hier ein "seek" allein nicht, da du damit nur an den Anfang der Datei/Puffer springst, du musst noch Mitteilen, dass du die den Dateiinhalt löschen willst, das macht du in dem du die Dateigröße auf "0" setzt, dazu dient "truncate".

Ich würde es so machen:

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
#!/ust/bin/perl
use strict;
use warnings;

my $file='./test.txt';

open (my $in, '+<', $file) or die("ERROR OPEN $file ($!)\n");
while(<$in>)
{
  if(/TESTWORT1/ .. /---/)
  {
    print "TESTWORT1 found\n";
    seek($in, 0,0);
    truncate($in,0);
  }
  else
  {
    print "TESTWORT1 not found\n";
  }
}
close($in);
print "EXIT\n";


etwas in der Art aus:
Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
TESTWORT1 not found
TESTWORT1 not found
TESTWORT1 not found
TESTWORT1 not found
TESTWORT1 not found
TESTWORT1 not found
TESTWORT1 not found
TESTWORT1 not found
TESTWORT1 not found
TESTWORT1 not found
TESTWORT1 not found
TESTWORT1 not found
TESTWORT1 not found
TESTWORT1 not found
TESTWORT1 found
EXIT


Ich werde nicht so recht schlau was du eigentlich machen willst. Der ganze Code ist reichlich unnütz, und der FlipFlop-Operator zudem.

Willst du nur die Zeile mit "TESTWORT1" aus der Datei löschen so musst du das ganze etwas komplexer angehen:
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='./test.txt';
open (my $fh, '+<', $file) or die("ERROR OPEN $file ($!)\n");
while(<$fh>)
{
  if(/TESTWORT1/ .. /---/)
  {
    print "TESTWORT1 found\n";

    # Aktuelle Dateigröße minus der Länge der Zeile
    my $size = (-s $fh) - length($_);
    # aktuelle Positon minus der Länge der Zeile
    my $pos=tell($fh) - length($_);

    # keine Zeilentrenner
    local $/=undef;
    # Alle daten auf einmal einlesen
    my $data=<$fh>;

    # zur Gespeicherten position springen
    seek($fh,$pos,0);

    # Daten schreiben, damit ist die aktuelle Zeile Gelöscht
    print $fh $data;

    # zum Anfang der datei springen
    seek($fh, 0,0);

    # Dateigröße anpasen
    truncate($fh,$size);
  }
}
close($fh);
print "EXIT\n";


Aber ich verstehe nicht warum die diesen ganzen Aufstand machst. Sind die Dateien mit denen du arbeitest so riesig, dass du sie nicht komplett im Speicher halten kannst? Da würde ich auf Module wie CPAN:Tie::File zurück greifen, das macht das ganze Gehampel mit truncate, seek und kopieren von sich aus transparent im Hintergrund.

Oder bist du, was ich eher glaube, nicht auf die Idee gekommen die Datei in ein Array zu Lesen und mit dem zu arbeiten?
Last edited: 2010-04-08 01:44:37 +0200 (CEST)

View full thread (re)open Textdatei