Schrift
[thread]8651[/thread]

Datei auslesen und best. pattern in hash speichern



<< |< 1 2 >| >> 17 Einträge, 2 Seiten
Duff
 2007-01-16 19:43
#73282 #73282
User since
2006-10-06
283 Artikel
BenutzerIn

user image
Hallo,

ich habe folgendes Problem. Ich habe eine Datei, in der einzelne Abschnitte sind. Aus diesen Abschnitten möchte ich bestimmte zeilen in (eigentlich nur 2) speichern.
Ich möchte es so machen, dass die erste gefundene Zeile mein Schlüssel ist und die zweite gefundene Zeile mein Wert ist.

Dazu habe ich folgendes gemacht:

Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
...
open(FILE, "<", $file)
while($z = <FILE>) {
if ($z =~ <mein pattern>) {
$key=$1;
chomp $key;
}
if ($z=~ <mein 2. pattern>){
$value=$1;
chomp $value;
}
$hash{$key}=$value;
}
close(FILE)


Dass ganze funktioniert auch soweit, wenn ich mir z.B. key und value in der while-Schleife ausgeben lasse.

Wenn ich mir aber in einer foreach $k (keys %hash) ... den Hash ausgeben lasse, so erhalte ich nur einen Schlüssel mit dem dazugehörigen Wert. Nämlich den letzten, der in der Datei gefunden wurde.

Wieso sehe ich nicht alle?
Der hash kann doch eigentlich nicht überschrieben werden, oder?\n\n

<!--EDIT|Duff|1168969439-->
D'OH
Daniel
renee
 2007-01-16 19:50
#73283 #73283
User since
2003-08-04
14371 Artikel
ModeratorIn
[Homepage] [default_avatar]
Du benutzt aber immer den gleichen Schlüssel. In einem Hash kann es einen Schlüssel nur ein einziges Mal geben. Du müsstest also mit einer Arrayreferenz arbeiten, damit Du alle "2.Zeilen" speicherst...

Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
open(FILE, "<", $file)
while($z = <FILE>) {
if ($z =~ <mein pattern>) {
$key=$1;
chomp $key;
}
if ($z=~ <mein 2. pattern>){
$value=$1;
chomp $value;
}
push @{$hash{$key}}, $value;
}
close(FILE)
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/
topeg
 2007-01-16 22:22
#73284 #73284
User since
2006-07-10
2611 Artikel
BenutzerIn

user image
Das Problem ist nicht nur das <mein pattern> häufiger auftauchen kann sondern auch, daß bei jedem Schleifendurchlauf der Wert im Hash geschrieben wird. Versuch es doch mal so:
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
open(FILE, "<", $file)
my $key;
while($z = <FILE>) {
my $value;
if ($z =~ <mein pattern>) {
$key=$1;
chomp $key;
}
elsif ($z=~ <mein 2. pattern> && $key ne ''){
$value=$1;
chomp $value;
}
if ($value ne '' && $key ne ''){
if(exists($hash{$key})){
push @{$hash{$key}}, $value;
}
else {
$hash{$key}=[$value];
}
$key='';
}
}
close(FILE);
renee
 2007-01-16 23:29
#73285 #73285
User since
2003-08-04
14371 Artikel
ModeratorIn
[Homepage] [default_avatar]
Das ist unnötig:
Code: (dl )
1
2
3
4
5
6
     if(exists($hash{$key})){
push @{$hash{$key}}, $value;
}
else {
$hash{$key}=[$value];
}


Mach einfach nur das push (ohne die Abfragen)...
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/
Duff
 2007-01-17 10:09
#73286 #73286
User since
2006-10-06
283 Artikel
BenutzerIn

user image
Der Schlüssel und der Wert sind jedes Mal unterschiedlich. Also ich verwende nicht immer den selben Schlüssel.

Was wohl gleich sein kann, ist der Wert.
D'OH
Daniel
renee
 2007-01-17 10:28
#73287 #73287
User since
2003-08-04
14371 Artikel
ModeratorIn
[Homepage] [default_avatar]
Dann poste doch mal Beispieldaten und was am Ende rauskommen soll...
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/
Duff
 2007-01-18 09:48
#73288 #73288
User since
2006-10-06
283 Artikel
BenutzerIn

user image
Also ich möchte eine Datei einlesen bzw. auswerten und dort nach bestimmten "Schlüsselwörtern" suchen.

Der Aufbau der Datei sieht in etwa so aus:

Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
[Name11]
text
text
test001
text

[Name12]
text
text
test002
text

[Name13]
text
text
test001
text

...


Ich möchte jetzt quasie die Datei einlesen Zeile für Zeile nach den Zeilen suchen, die brauche, und wie folgt speichern.

Z.B.

hash{test001}=[NAME11, NAM13]
hash{test002}=[Name12]
usw.

Ich möchte also einen Hash haben, der einen Schlüssel hat und dessen Wert aus einem Element besteht oder aus mehreren, also dessen Wert ein Array ist.

Hoffe, dass es halbwegs verständlich ist.
D'OH
Daniel
renee
 2007-01-18 10:24
#73289 #73289
User since
2003-08-04
14371 Artikel
ModeratorIn
[Homepage] [default_avatar]
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
#!/usr/bin/perl

use strict;
use warnings;
use Data::Dumper;

# Datei die überprüft werden soll
my $file = '/path/to/file';
# alle Pattern
my @pattern = qw(test001 test002);
# Hash mit Ergebnissen
my %hash;

{
open my $fh, '<',$file or die $!;
local $/ = "\n\n"; # $/ auf "Leerzeile" setzen
while(my $entry = <$fh>){
my ($key) = $entry =~ m!\[(.*?)\]!;
for my $line(split(/\n/,$entry)){
for my $pat(@pattern){
if($line =~ /\Q$pat\E/){
push @{$hash{$pat}},$key;
next;
}
}
}
}
close $fh;
}

print Dumper(\%hash);


ungetestet...
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/
Duff
 2007-01-18 12:21
#73290 #73290
User since
2006-10-06
283 Artikel
BenutzerIn

user image
Ja danke.

Aber das ganze soll in dem Hash genau anders herum gespeichert werden. Nämlich ungefähr so:

Code: (dl )
1
2
hash{test001}=[NAME11, NAM13]
hash{test002}=[Name12]


Ich habe jetzt so versucht, dass ich das Array @pattern zuerst erstelle, in dem ich über die Datei gehe und nach meinem Suchausdruck suche und diesen in dem Array @pattern speichere.

Danach mache ich dann das, was du mir vorgeschlagen hast. Die Frage ist nur, ob das ganze effizient ist, weil ich ja die Datei insgesamt 2mal öffne und schließe.

Kannst du mir eventuell mal kurz erklären, was das $local und damit das split genau macht in diesem Beispiel?

Danke.
D'OH
Daniel
renee
 2007-01-18 12:41
#73291 #73291
User since
2003-08-04
14371 Artikel
ModeratorIn
[Homepage] [default_avatar]
Genauso wird es auch gespeichert...

Du musst doch schon vorher wissen, welche Pattern du hast, oder? Wenn nicht, dann musst Du hier mal deutlicher darlegen, welche Informationen Du hast...

$/ ist eine Spezialvariable von Perl (siehe perlvar). Das local bewirkt, dass für den aktuellen Block ein anderer Wert für $/ genommen wird. So kann man bei klar abgegrenzten Einträgen das Einlesen komfortabler machen. Diese Veränderung hat aber nichts mit dem split zu tun.

Durch das Verändern von $/ lese ich ganze Blöcke ein und nicht nur einzelne Zeichen. Ein Block ist z.B.
Code: (dl )
1
2
3
4
5
[Name12]
text
text
test002
text
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/
<< |< 1 2 >| >> 17 Einträge, 2 Seiten



View all threads created 2007-01-16 19:43.