Schrift
Wiki:Tipp zum Debugging: use Data::Dumper; local $Data::Dumper::Useqq = 1; print Dumper \@var;
[thread]8662[/thread]

Probleme mit dem Speichern von Dateinamen

Leser: 1


<< >> 9 Einträge, 1 Seite
Timo_81
 2007-01-20 17:58
#73391 #73391
User since
2006-09-12
10 Artikel
BenutzerIn
[Homepage] [default_avatar]
Hi ,
ich habe mit meinem Programm mehrere Dateien aus einem Array geöffnet.
Es handelt sich um Texdateien.Nun möchte ich die Sätze einzeln extrahieren
und in eine Datein mit Nummerierung schreiben (Das geht auch).

Nun möchte ich auch eine weitere Datei erstellen ,die die Dateien aus denen
die Sätze extrahiert wurden ,gespeichert werden, um sie später wieder zuordnen zu können.

Leider hat @Liste die eigentlich die Dateinamen zu den Sätzen speichern soll viel zu viele Einträge .

Hier die relevanten Codeausschnitte:

Code: (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
38
39
40
41
42
43
44
45
46
47
my $data; # Arbeitsvariable
my $datei;
for my $file (@textdateien)
{
open DAT, $file;
push(@liste,$file); #SPEICHER DIE DATEI IN EIN ARRAY
for my $line (<DAT>)
{

chomp $line; # Den Zeilenumbruch am Ende entfernen
$data .= $line; # und diese Zeile anhängen,falls es über mehrere Zeilen geht


push(@liste,$file);# das führt leider zu zuvielen Dateinamen!
my @saetze = split/(?<=[\.!?])\s*/, $data; #Filtert Sätze raus


open DATEI, ">out.txt"; # Die Ausgabedatei

$counter = 0; # counter initialisieren

for (@saetze)
{

print DATEI $counter++, "; $_ \n"; #Enthält die ID und die Sätze

}

close DATEI;


close DAT;
}

################################################################
#Hier sollen nun die Dateinamen zu den Sätzen gespeichert werden
################################################################
}
open DATEI ,">verweis.txt"; #Enthält die ID und die Dateinamen

foreach(@liste) #KOMMT LEIDER Mist RAUS
{
$counter2++;
print DATEI $counter2.";"."$_\n";

}
close DATEI;


Ich bin mit meinem Latein am Ende!
Hoffe jemand kann mir helfen
Gruß
Timo
renee
 2007-01-20 18:12
#73392 #73392
User since
2003-08-04
14371 Artikel
ModeratorIn
[Homepage] [default_avatar]
Du solltest vielleicht etwas genauer beschreiben, was Du machen willst. Du schiebst den Dateinamen erstmal direkt nach dem Öffnen der Datei in das Array. Dann bei jeder eingelesenen Zeile...
OTRS-Erweiterungen (http://feature-addons.de/)
Frankfurt Perlmongers (http://frankfurt.pm/)
--

Unterlagen OTRS-Workshop 2012: http://otrs.perl-services.de/workshop.html
Perl-Entwicklung: http://perl-services.de/
Timo_81
 2007-01-20 18:38
#73393 #73393
User since
2006-09-12
10 Artikel
BenutzerIn
[Homepage] [default_avatar]
Hi ,
danke für deine schnelle Antwort.

Nun ich möchte einfach die Dateien zu den eingelesenen Sätzen in eine Datei
speichern. Deshalb dachte ich muss das beim öffnen in ein Array schreiben.


Ich mach mal ne Beispiel

Sagen wir haben

Satz1: Heute ist Sommer.
Satz2. Gestern war Sonntag.
Satz3. Wer hat angerufen?


Dann (das funktioniert schon):

erstellt er eine Datei und macht

1;Heute ist Sommer.
2;Gestern war Sonntag.
3;Wer hat angerufen.

Nun soll er noch eine neue Datei anlegen und die Dateinamen in denen
die Sätze gestanden hatten aufgeführt werden

1;Datei1
2;Datei1 (könnte ja auch da dringestanden haben)
3;Datei5

damit man es später zuordnen kann
Gruß
Timo
topeg
 2007-01-20 19:11
#73394 #73394
User since
2006-07-10
2611 Artikel
BenutzerIn

user image
Für sowas sind Hashes genau gedacht:
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
my %saetze_gefunden;
for my $file (@textdateien)
{
  # gesammte Datei einlesen
  local $/='';
  open (DATEI, '<', $file) or die "Konnte '$file' nicht öffnen ($!)\n";
  # Datei in sätze zerlegen
  (my $daten=<DATEI>)=~s/[\r\n]//gs;
  my @saetze_datei=split(/(?<=[\.!?])\s*/,$daten);
  close(DATEI);
  # Alle Sätze durchgehen und dem Hash als Schüssel werwenden.
  # Als Wert ist ein Array enthalten, das die Dateinamen aufnimmt.
  push(@{$saetze_gefunden{$satz}},$file) for my $satz (@saetze_datei);
}

open (REFDAT,'>','verweis.txt') or die "Konnte 'verweis.txt' nicht öffnen ($!)\n";
open (OUTDAT,'>','out.txt') or die "Konnte 'out.txt' nicht öffnen ($!)\n";
# Den Hash durchgehen und die Werte in die Dateien schreiben.
my $cnt=0;
for my $satz (keys(%saetze_gefunden))
{
  print OUTDAT "$cnt:$satz\n";
  print REFDAT "$cnt:".join(',',@{$saetze_gefunden{$satz}})."\n";
  $cnt++;
}
close (OUTDAT);
close (REFDAT);


EDIT: die zeile
Code: (dl )
my @saetze_datei=split(/(?<=[\.!?])\s*/,<DATEI>);
nach
Code: (dl )
1
2
  (my $daten=<DATEI>)=~s/[\r\n]//gs;
my @saetze_datei=split(/(?<=[\.!?])\s*/,$daten);
geändert, um die Zeilenumbrüche zu entfernen.\n\n

<!--EDIT|topeg|1169317516-->
Timo_81
 2007-01-20 19:25
#73395 #73395
User since
2006-09-12
10 Artikel
BenutzerIn
[Homepage] [default_avatar]
Danke für dein Antwort.
Mit dem Code den ich hatte geht es nicht?

Gruß
Timo
Timo_81
 2007-01-20 20:12
#73396 #73396
User since
2006-09-12
10 Artikel
BenutzerIn
[Homepage] [default_avatar]
Hi , mein altes Programm hatte über 500 Sätze gefunden. Die modifizierte Version über 300.
Kann das sein das da welche übersprungen wurden?


Gruß
Timo
topeg
 2007-01-20 20:18
#73397 #73397
User since
2006-07-10
2611 Artikel
BenutzerIn

user image
Das der Code speichert alle Sätze, auch jene die doppelt vorkommen, mit jeweils einer eigenen IDNummer. Du bräuchtest noch ein übergeordnetes Array, in dem alle Sätze drinstehen, die schon gelesen wurden. Das array müßtest du bei jedem Weiteren Satz durchgehen und schauen, ob der Neue Satz schonmal da war.
Dann bräuchtest du noch ein Array in dem Die ganzen Dateinamen (in einem untergordenten Array oder als Stringliste) zu den dazugehörigen IDs aufgelistet sind, du kannst ja nicht vorher wissen in welcher Datei welcher Satz auftaucht. Erst zum Schluss wenn du alle Dateien geparst hast, kannst du die Dateien "out.txt" und "verweis.txt" schreiben.
Wenn du allso deinen Ansatz weiterverfolgst wird das genze sehr viel komplizierter, als wenn du einen Hash benutzt.

Aber man kann es so machen, wie du Angefangen hast:

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
38
39
my @alle_saetze;
my @dateien;
for my $file (@textdateien)  
{
  local $/='';
  open(DAT, '<',$file) or die "'$file' $!\n";
  # Datei ganz einlesen (siehe oben $/)
  # und Zeilenumrüche entfernen
  # (Habe ich bei meinem Beispiel vergessen :-/ )
  (my $data=<DAT>)=~s/[\r\n]+//gs;
  close(DAT);
  my @saetze = split/(?<=[\.!?])\s*/, $data; #Filtert Sätze raus
  for my $satz (@saetze)
  {
    # nach dem Satz im Array @alle_saetze suchen
     my $pos=0;
     $pos++ while($alle_saetze[$pos] ne $satz && $pos<@alle_saetze);
    # kein gleicher Satz gefunden,
    # da die Schleife alle Sätze durchgegangen ist.
    if( $pos == @alle_saetze);
    {
      push(@alle_saetze,$satz);
      push(@dateien,[$file]);
    }
    # Den Satz gibt es schon.
    else
    {  push(@$dateien[$pos],$file);  }
  }
}

# Die Ausgabedatei
open(DATEI, '>', 'out.txt') or die 'out.txt: $!\n';
print "$i:$alle_saetze[$i]\n" for my $i (0..$#alle_saetze);
close(DATEI);

#Enthält die ID und die Dateinamen
open DATEI ,'>', 'verweis.txt' or die 'verweis.txt: $!\n';
print "$i:".join(',',@$dateien[$i])."\n" for my $i (0..$#dateien);
close DATEI;


Du must doch zugeben, das die Variante über einen Hash doch etwas eleganter ist. :-)
Timo_81
 2007-01-20 20:32
#73398 #73398
User since
2006-09-12
10 Artikel
BenutzerIn
[Homepage] [default_avatar]
Hi ,
klar eleganter nur auch etwas schwerer nachzuvollziehen.
Danke für die prompte Antwort.
Du glaubst gar nicht wie lange ich an den gleichen Sätzen schon rummache!

Denn auf das läuft es raus ;)

Xie Xie
Timo
topeg
 2007-01-20 20:47
#73399 #73399
User since
2006-07-10
2611 Artikel
BenutzerIn

user image
Ach noch eine Kleinigkeit.
Es wäre günstig die Sätze zu "vereinheitlichen." Es kann ja sein, daß Tabulatoren oder mehrere Leerzeichen verwendet wurden. Weiterhin ist es nicht selbstverständlich, daß am Ende einer Zeile vor dem Zeilenumbruch ein Leerzeichen vorkommt.
Es wäre allso günstig wie die den Inhalt der Dateien wie folgt zu formatieren:
Code (perl): (dl )
1
2
$data=~s/[\r\n]+/ /gs;
$data=~s/\s+/ /g;
<< >> 9 Einträge, 1 Seite



View all threads created 2007-01-20 17:58.