Schrift
[thread]6022[/thread]

Datei lesen und in Hash schreiben? (Seite 5)

Leser: 2


<< |< 1 2 3 4 5 >| >> 46 Einträge, 5 Seiten
Patrick
 2004-01-20 16:08
#79282 #79282
User since
2004-01-07
56 Artikel
BenutzerIn
[default_avatar]
Wo müsste ich die Änderung im Codeabschnitt vornehmen um die Kommentare einzufügen?

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
sub insert_keys
{
  my ($bufferp, $paramp, $komment) = @_;

# entfernt RETURN
  chomp ($komment);

# Was macht das?   "$$" -> ?????
  return unless defined $$bufferp && length $$bufferp;

  die "Syntaxfehler in Zeile $." unless index ($$bufferp, '=') >= 0;
  my ($key, $val) = split /\s*=\s*/, $$bufferp, 2;

#   print "$$bufferp  - $komment \n";


# Ab hier muss ich was änder (glaube ich) aber was???

  unless (defined $val)
  {
      $paramp->{$key} = undef;
      return;
  }
  if ($val =~ /\s/)   # Leerzeichen zwischen Woertern? => Liste
  {
      my @vals = split " ", $val;
      $paramp->{$key} = \@vals;
  }
  else
  {
      $paramp->{$key} = $val;
  }
  $$bufferp = "";
}
Mfg
Paddy

Perl ist göttlich, die Kunst besteht darin Perl anwenden zu können.
Dubu
 2004-01-20 16:35
#79283 #79283
User since
2003-08-04
2145 Artikel
ModeratorIn + EditorIn

user image
[quote=Patrick,20.01.2004, 14:49]Am günstigsten wäre es wohl, wenn Die Datei so wieder rauskommt, wie man sie gelesen hat.
Abgesehen von den veränderten Werten.
[/quote]
Ah, okay. Du willst eine Datei einlesen, ein paar Werte austauschen und dann wieder schreiben. Und die Kommentare sollen wohl jeweils den Werten und nicht den Schluesseln zugeordnet sein. Hm. Das wird etwas schwieriger.

Quote
Wäre eine Idee die Kommentare, die schon ausgegeben wurden zu löschen, damit diese nicht nochmal drankommen bei z.B. Listen.

Das habe ich jetzt nicht verstanden.
Was fuer "Kommentare, die schon ausgegeben wurden"?

Hier ist erstmal eine Version, die die Kommentare zu jedem Schluessel gesammelt speichert:
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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
#!/usr/bin/perl
use strict;
use warnings;

my %params;

open PARAM, "param.dat" or die $!;

my $buffer = '';
my $commentbuffer = '';
while (<PARAM>) {
   # Kommentare extrahieren
   if (s/\s*#\s*(.*?)\s*(\\?\n)/$2/) {
       my $ctemp = $1;
       if (length $ctemp) {
           if (length $commentbuffer) {
               $commentbuffer .= "\n" . $ctemp;
           } else {
               $commentbuffer = $ctemp;
           }
       }
   }

   # Leerzeichen an Anfang und Ende loeschen
   s/^\s+//;
   s/\s+$//;

   # Zeile jetzt leer?
   unless (length) {
       # vorhandenen Buffer bearbeiten
       insert_keys (\$buffer, \$commentbuffer, \%params);
       next;
   }

   # Zeile merken
   $buffer .= $_;
   if ($buffer =~ /\\$/) {    # Fortsetzung folgt?
       # Fortsetzungszeichen durch Leerzeichen ersetzen
       chop $buffer; $buffer .= " ";
       next;
   }
   insert_keys (\$buffer, \$commentbuffer, \%params);

}
# Falls die letzte Zeile noch ein Fortsetzungszeichen hatte ...
insert_keys (\$buffer, \$commentbuffer, \%params);


use Data::Dumper;
print Dumper \%params;

#############################################
sub insert_keys {
   my ($bufferp, $cbufferp, $paramp) = @_;
   return unless defined $$bufferp && length $$bufferp;

   die "Syntaxfehler in Zeile $." unless index ($$bufferp, '=') >= 0;
   my ($key, $val) = split /\s*=\s*/, $$bufferp, 2;


   unless (defined $val) {
       $paramp->{$key} = undef;
       return;
   }
   if ($val =~ /\s/) { # Leerzeichen zwischen Woertern? => Liste
       my @vals = split " ", $val;
       $paramp->{$key}{wert} = \@vals;
   } else {
       $paramp->{$key}{wert} = $val;
   }
   $paramp->{$key}{comment} = $$cbufferp;
   $$cbufferp = "";
   $$bufferp = "";
}

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

Wie ist das denn:
Aenderst du nur einzelne Werte oder werden auch welche hinzugefuegt oder geloescht? Kommen auch Schluessel hinzu/weg? Steht eigentlich immer ein Wert in einer eigenen Zeile, oder koennen auch mehrere hintereinander stehen, z.B. so?
Code: (dl )
1
2
KEY = foo bar \
      baz # ergibt die Werte foo, bar und baz fuer KEY
Patrick
 2004-01-20 16:56
#79284 #79284
User since
2004-01-07
56 Artikel
BenutzerIn
[default_avatar]
[quote=Dubu,20.01.2004, 15:35]
Wie ist das denn:
Aenderst du nur einzelne Werte oder werden auch welche hinzugefuegt oder geloescht? Kommen auch Schluessel hinzu/weg? Steht eigentlich immer ein Wert in einer eigenen Zeile, oder koennen auch mehrere hintereinander stehen, z.B. so?
Code: (dl )
1
2
KEY = foo bar \
      baz # ergibt die Werte foo, bar und baz fuer KEY

[/quote]

Ich möchte teilweise einzelne Werte setzen.

Bei einem jedoch können durchaus auch bis zu 20 oder mehr Werte eingetragen werden.

Z.B.:
Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
.
.
LIST1    = Wert1                          # Kommentar
LIST2    = Wert1                          # Kommentar   \
             Wert2                          # Kommentar   \
     eigener Wert4                        # Kommentar   \
     eigener Wert5                        # Kommentar   \
     eigener Wert6                        # Kommentar   \

STARTLIST  = test.ids             # List
.
.


Da muss ich wohl Elemente einfügen!
Mfg
Paddy

Perl ist göttlich, die Kunst besteht darin Perl anwenden zu können.
Dubu
 2004-01-20 18:28
#79285 #79285
User since
2003-08-04
2145 Artikel
ModeratorIn + EditorIn

user image
Na gut... ;)

Hier ist eine Version, die mit der bisherigen Spezifikation zurecht kommt. Um die Datenstruktur etwas klarer zu machen, habe ich gleich noch eine Ausgabe dazu programmiert. Bis auf Whitespace wird damit die Originaldatei rekonstruiert, inkl. Reihenfolge der Schluessel und Werte.

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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
#!/usr/bin/perl
use strict;
use warnings;

my %params;

open PARAM, "param.dat" or die $!;

my $currentkeyword = '';
my $currentvalue = '';
my @freecomments = ();
my $continued = 0;
while (<PARAM>) {
   chomp;
   # Leerzeichen vorne/hinten loeschen
   s/^\s+//;
   s/\s+$//;

   # Diese Zeile fortsetzen?
   if (/\\$/) {
       chop;
       # evtl. nochmal Leerzeichen am Ende loeschen
       s/\s+$//;
       $continued = 1;
   } else {
       $continued = 0;
   }

   if (/^#\s*(.*)/) {  # nur Kommentar
       if (length $currentkeyword && length $currentvalue) {   # Kommentar zu einem Wert
           push @{$params{$currentkeyword}{comments}{$currentvalue}}, $1;
       } else {                # freier Kommentar
           push @freecomments, $1;
       }
   } elsif (length) {          # keine Leerzeile
       my ($ktemp, $ctemp);    # Hilfsvariablen

       if (/^(.+?)\s*#\s*(.*)/) {      # Zeile mit Kommentar?
           ($ktemp, $ctemp) = ($1, $2);
       } else {
           ($ktemp, $ctemp) = ($_, '');
       }

       if (length $currentkeyword) {   # Wenn es ein aktuelles Keyword gibt ...
           $currentvalue = $ktemp;     # ... Wert merken ...
       } elsif (index ($ktemp, '=') >=0) { # ansonsten muss es "Schluessel = Wert" sein
           ($currentkeyword, $currentvalue) = split /\s*=\s*/, $ktemp, 2;
           push @{$params{keywords}}, $currentkeyword;
       } else {                        # keine korrekte Syntax
           die "Syntaxfehler in Zeile $.";
       }
       # Jetzt neuen Wert im Array @{$params{$currentkeyword}{values}} merken ...
       push @{$params{$currentkeyword}{values}}, $currentvalue;
       # ... und evtl. Kommentar dazu im Array @{$params{$currentkeyword}{comments}{$currentvalue}} ablegen.
       push @{$params{$currentkeyword}{comments}{$currentvalue}}, $ctemp if length $ctemp;
   }

   # Wenn die naechste Zeile Fortsetzung ist, bei neuer Zeile weiter ...
   next if $continued;

   # ... ansonsten freie Kommentare beim Keyword speichern und Keyword loeschen
   if (length $currentkeyword && @freecomments) {
       @{$params{$currentkeyword}{precomments}} = ( @freecomments );
       @freecomments = ();
   }
   ($currentkeyword, $currentvalue) = ('', '');

}

#### Testausgabe!
# use Data::Dumper;
# print Dumper \%params;
# exit;

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

# Jetzt wieder ausgeben!

# Fuer alle Keywords
for my $key (@{$params{keywords}}) {
   # erst die freien Kommentare, falls vorhanden
   if (exists $params{$key}{precomments}) {
       print "# ", $_, "\n" for @{$params{$key}{precomments}};
   }

   # dann die einzelnen Schluessel und Werte
   print "$key = ";
   my @vals = ();
   foreach my $val (@{$params{$key}{values}}) {
       my $str = $val;
       if (exists $params{$key}{comments}{$val}) {
           $str .= "\t# " . join " \\\n\t\t\t# ", @{$params{$key}{comments}{$val}};
       }
       push @vals, $str;
   }
   print join " \\\n\t\t", @vals;
   print "\n";
}


Edit: Die Datenstruktur sieht uebrigens wie folgt aus.

Der Hash %params hat
- einen Eintrag keywords, in dem alle Schluesselworte in der Reihenfolge ihres Vorkommens stehen und
- fuer jedes Schluesselwort einen weiteren Eintrag.

Jeder Schluesselworteintrag verweist auf einen Hash mit folgenden Eintraegen:
* 'precomments' - zeigt auf eine Array mit Kommentaren, die vor der Zeile mit diesem Schluessel standen,
* 'values' - zeigt auf ein Array mit den Werten fuer diesen Schluessel, in der Reihenfolge ihres Auftretens
* 'comments' - zeigt wiederum auf einen Hash, der fuer jeden kommentierten Wert die Kommentare enthaelt.

'precomments' und 'comments' sind dabei fakultativ, d.h. nur nach Bedarf gefuellt. 'values' enthaelt mindestens einen Wert, der aber leer sein kann.\n\n

<!--EDIT|Dubu|1074616626-->
Patrick
 2004-01-21 08:33
#79286 #79286
User since
2004-01-07
56 Artikel
BenutzerIn
[default_avatar]
Mensch Ihr seid Göttlich!

Wo und wie müsste ich denn ansetzen um auf bestimmte Werte zuzugreifen und eventuell zu ändern?

Nochmal vielen Dank
Mfg
Paddy

Perl ist göttlich, die Kunst besteht darin Perl anwenden zu können.
Dubu
 2004-01-21 11:25
#79287 #79287
User since
2003-08-04
2145 Artikel
ModeratorIn + EditorIn

user image
[quote=Patrick,21.01.2004, 07:33]Wo und wie müsste ich denn ansetzen um auf bestimmte Werte zuzugreifen und eventuell zu ändern?[/quote]
So:
Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
...
# Werte zu vorhandenen Schluesseln ausgeben
print @{$params{VORHANDENESKEYWORD}{values}};

# Werte zu vorhandenen Schluesseln aendern
@{$params{DEINKEYWORD}{values}} = ("DEINWERT1", "DEINWERT2", ...);
# Kommentare dazu setzen
@{$params{DEINKEYWORD}{comments}{DEINWERT1}} = ("Kommentarzeile 1 zu Wert 1", "Kommentarzeile 2 zu Wert 1");
@{$params{DEINKEYWORD}{comments}{DEINWERT2}} = ("Hier der Kommentar zu Wert 2");

...
# Neues Schluesselwort anlegen
push @{$params{keywords}}, "NEUESKEYWORD";
# Werte dazu
@{$params{NEUESKEYWORD}{values}} = ("NEUERWERT1", "NEUERWERT2", ...);
# ... etc.

Und zum Ausgeben den unteren Teil von meinem Code oben. :)
<< |< 1 2 3 4 5 >| >> 46 Einträge, 5 Seiten



View all threads created 2004-01-18 22:12.