Schrift
[thread]11622[/thread]

aus HTML auslesen

Leser: 1


<< |< 1 2 3 >| >> 25 Einträge, 3 Seiten
rioc
 2008-04-11 15:24
#108229 #108229
User since
2008-04-11
15 Artikel
BenutzerIn
[default_avatar]
Hallo zusammen

Ich bin noch nicht sehr lange mit PERL am scripten, habe jedoch etwas Erfahrung aus anderen Programmiersprachen.

Meine Aufgabe ist es, ein Script zu schreiben, welches Server-Infos aus einer Ausgabedatei von cfg2html entnimmt, und diese in einer überslichtlicheren HTML-Seite darzustellen (da cfg2html ein eher unübersichtliches Ergebnis liefert, und meine Vorgesetzten gewisse Infos auf einen Blick haben möchten).

d.h. also ich lese aus einer HTML datei Infos aus, und schreibe diese in ein anderes HTML File.

hier zunächst mal zwei Code-Ausschnitte, die mir Probleme liefern:
#1
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
foreach $line (@data)
{
        if  ($line =~ /start:/)
        {
                @stst = (split /\:/, $line);
                print "<font size=+2>$stst[1]</font size>\n";
                print "<table cols=7 BORDER=1 cellpadding=1 cellspacing=1>\n";
                print "<tr>\n";
                print   "<td width=150 align=right><b>Hostname</b></td>\n";
                print   "<td width=120 align=right><b>IP-Adresse</b></td>\n";
                print   "<td width=150 align=right><b>Model</b></td>\n";
                print   "<td width=80 align=right><b>uptime (d)</b></td>\n";
                print   "<td width=60 align=right><b>OS</b></td>\n";
                print   "<td width=100 align=right><b>Last Update</b></td>\n";
                print   "<td width=50 align=right><b>SN</b></td>\n";
                print "</tr>";
        }
        elsif ($line =~ /end:/)
        {
                print "</table>\n";
                print "<br><br>\n";
        }
        else 
        {
                print "<tr>";
                $file=$path . ".html" . $line;
                if (-f $file)
                {
                open(TEMP,$file);
                }
                else
                {
                @myunkn= split /\./, $file,3;
                $myunknown=$myunkn[0] . "." . $myunkn[1];               
                open(TEMP,$myunknown);
                $file=$myunknown;
                }
                
                @lines=<TEMP>;


#2
Code (perl): (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
                @Host=grep {/Host:/} @lines;
                @AHost=split (/ /,$Host[0]);
                $filepath=$htmlpath . $line . ".html";

                @Domain=grep {/DNS domain name:/} @lines;
                @ADomain=split (/    /,$Domain[0]);


                print "<td width=150 align=right><a href=$filepath>$AHost[1].$ADomain</a></td>\n";

                @IP=grep {/IPAdress:/} @lines;
                print "<td width=150 align=right>";
                foreach $run (@IP)
                {
                        @AIP=split (/   /,$run);
                        print $AIP[1] . "<br>";
                }
                print "</td>\n";
(von Ausschnitt 2 gibt es noch weitere Infos die ausgelesen werden, diese sind jedoch im gleichen Stil gecoded. Ich führe diese hier nicht auf um platz zu sparen)

die Fehlermeldungen:

zu Ausschnitt 1:

readline() on closed filehandle TEMP at listhosts.pl line 124.
(Zeile 124 ist: @lines=<TEMP>;) (hier also Zeile 39)
(ich habe die vorangehenden Zeilen mitgeliefert, da vielleicht das Problem weiter oben bedingt ist.)

zu Ausschnitt 2:

Use of uninitialized value in split at listhosts.pl
Use of uninitialized value in concatenation (.) or string at listhosts.pl


Ich danke schon im Voraus :)

Grüsse rioc
renee
 2008-04-11 15:43
#108230 #108230
User since
2003-08-04
14371 Artikel
ModeratorIn
[Homepage] [default_avatar]
Generell solltest Du beim öffnen von Dateien auch Fehlerabfragen machen, also open(TEMP,$file) or die "Can't open $file: $!";

Außerdem solltest Du Dir mal diesen Wiki:Artikel durchlesen.

Desweiteren brauchst Du nicht jede einzelne Zeile ausgeben.

Du kannst aus
Code (perl): (dl )
1
2
3
print "zeile";
print "zeile2";
print "zeile3";


das hier machen:
Code (perl): (dl )
1
2
3
print "zeile",
    "zeile2",
    "zeile3";



Wenn Du dann etwas weiter bist, kannst Du Dir ja mal Templating-Systeme wie CPAN:HTML::Template::Compiled anschauen, damit die HTML-Ausgabe nicht im Skript gemacht wird.

@lines ist ja leer - auf Grund Deines ersten Problems, deswegen gibt es die Warnung...
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/
rioc
 2008-04-11 15:57
#108231 #108231
User since
2008-04-11
15 Artikel
BenutzerIn
[default_avatar]
danke für die schnelle Antwort. den Artikel werde ich gleich durchlesen...

und bei weiteren Fragen wieder melden ;)
nepos
 2008-04-11 16:46
#108232 #108232
User since
2005-08-17
1420 Artikel
BenutzerIn
[Homepage] [default_avatar]
Oder zumindest die von CPAN:CGI bereitgestellten Funktionen zum Erzeugen von sauberem HTML benutzen.
rioc
 2008-04-21 13:12
#108624 #108624
User since
2008-04-11
15 Artikel
BenutzerIn
[default_avatar]
dass ich den "or die" befehl vergessen habe ist ein flüchtigkeitsfehler, mache ich in der Regel immer...

hab noch das mit dem "print" auf mehrere Zeilen verteilt versucht, jedoch funzt das bei mir so net... vielleicht weil es auf einer HP-UX kiste läuft?

den "Readline() on closed filehandle" bin ich so losgeworden, jedoch tauchen die "
Code: (dl )
Use of uninitialized value in split" und "Use of uninitialized value in concatenation (.) or string
" immernoch auf...

Hier mal die Initialisation des Scripts:

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
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
#!/opt/perl5/bin/perl -w
# die $path -variable repraesentiert den Pfad zu den collect-files

$htmlbasepath="/";
$htmlpath=$htmlbasepath . "cfg2html/server/";

#$basepath="/web/html/";
$basepath="/home/rioc/Desktop/perl_test/";
$path=$basepath . "cfg2html/server/";


opendir(DIRHANDLE, $path) or die "Directory not available";

while ( defined ($filename = readdir(DIRHANDLE)))
{
        @list=(@list,$filename);
}
@list=sort (@list);
@machinelist = grep {/.html/} @list;

@allmachines=();

foreach $machine (@machinelist)
{
$machine =~ s///;
@allmachines=(@allmachines,$machine);
}



@domains=();

foreach $machine (@allmachines)
{
        $ok=0;
        @splitpieces = split /\./, $machine;
        if ($splitpieces[1])
        {
        $dmn=$splitpieces[1]
        }
        else
        {
        $dmn="unknown";
        $splitpieces[1]="unknown";
        }       
        foreach $try (@domains)
        {
                if ($try eq $dmn) {$ok=1};
        };
        if ($ok ne 1) {@domains=(@domains,$dmn)};
        $ok=0;

        $machine = join '.', @splitpieces;
};

@domains=sort(@domains);
@data=();
foreach $domain (@domains)
{
        @$domain=();
        foreach $machine (@allmachines)
        {
                @namepartsplit= split /\./, $machine;
                if ( $namepartsplit[1] eq $domain )
                {
                        @$domain=(@$domain,$machine);
                };
        };
@data=(@data,"start:$domain",@$domain,"end:$domain",);
};


und hier den Teil der die Infos aus dem HTML entnimmt:

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
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
foreach $line (@data)
{
        if  ($line =~ /start:/)
        {
                @stst = (split /\:/, $line);
                print "<font size=+2>$stst[1]</font size>\n",
                print "<table cols=7 BORDER=1 cellpadding=1 cellspacing=1>\n",
                print "<tr>\n",
                print   "<td width=150 align=right><b>Hostname</b></td>\n",
                print   "<td width=120 align=right><b>IP-Adresse</b></td>\n",
                print   "<td width=150 align=right><b>Model</b></td>\n",
                print   "<td width=80 align=right><b>uptime (d)</b></td>\n",
                print   "<td width=60 align=right><b>OS</b></td>\n",
                print   "<td width=100 align=right><b>Last Update</b></td>\n",
                print   "<td width=50 align=right><b>SN</b></td>\n",
                print "</tr>";
        }
        elsif ($line =~ /end:/)
        {
                print "</table>\n";
                print "<br><br>\n";
        }
        else 
        {
                print "<tr>";
                $file=$path . $line;
                if (-f $file)
                {
                open(TEMP,$file)or die "Can't open $file: $!";
                }
                else
                {
                @myunkn= split /\./, $file,3;
                $myunknown=$myunkn[0] . "." . $myunkn[1];               
                open(TEMP,$myunknown) or die "Can't open $file: $!";
                $file=$myunknown;
                }
                
                @lines=<TEMP>;
                
                @Host=grep {/Host:/} @lines;
                @AHost=split (/ /,$Host[0]);
                $filepath=$htmlpath . $line;

                @Domain=grep {/DNS domain name:/} @lines;
                @ADomain=split (/    /,$Domain[0]);


                print "<td width=150 align=right><a href=$filepath>$AHost[1] . $ADomain</a></td>\n";

                @IP=grep {/IPAdress:/} @lines;
                print "<td width=150 align=right>";
                foreach $run (@IP)
                {
                        @AIP=split (/   /,$run);
                        print $AIP[1] . "<br>";
                }
                print "</td>\n";
                
                @Model=grep {/Model:/} @lines;
                @AModel=split (/        /,$Model[0]);
                print "<td width=150 align=right>$AModel[1]</td>\n";

[...]
... hier wären weitere greps im gleichen Stil verfasst ...
[...]           

                @SN=grep {/serialNumber/} @lines;
                @ASN=split (/=/,$SN[0]);
                print "<td width=150 align=right>$ASN[1]</td>\n";               
                
                print "</tr>";
        };


das problem ist: 2 der Gesuchten Infos werden gefunden (SerialNumber & Host, beispielsweise), jedoch kommt beim rest die "Use of uninitialized value in split" Meldung, obwohl der split-Parameter richtig ist...


freundliche Grüsse
rioc
pq
 2008-04-21 13:53
#108627 #108627
User since
2003-08-04
12208 Artikel
Admin1
[Homepage]
user image
rioc+2008-04-11 13:24:15--
Code (perl): (dl )
1
2
3
4
5
6
7
8
9
10
11
                print "<font size=+2>$stst[1]</font size>\n";
                print "<table cols=7 BORDER=1 cellpadding=1 cellspacing=1>\n";
                print "<tr>\n";
                print   "<td width=150 align=right><b>Hostname</b></td>\n";
                print   "<td width=120 align=right><b>IP-Adresse</b></td>\n";
                print   "<td width=150 align=right><b>Model</b></td>\n";
                print   "<td width=80 align=right><b>uptime (d)</b></td>\n";
                print   "<td width=60 align=right><b>OS</b></td>\n";
                print   "<td width=100 align=right><b>Last Update</b></td>\n";
                print   "<td width=50 align=right><b>SN</b></td>\n";
                print "</tr>";

hui.
Code (perl): (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
print <<"EOM";
<font size="+2">$stst[1]</font>
<table cols=7 BORDER=1 cellpadding=1 cellspacing=1>
<tr>
<td width=150 align=right><b>Hostname</b></td>
<td width=120 align=right><b>IP-Adresse</b></td>
<td width=150 align=right><b>Model</b></td>
<td width=80 align=right><b>uptime (d)</b></td>
<td width=60 align=right><b>OS</b></td>
<td width=100 align=right><b>Last Update</b></td>
<td width=50 align=right><b>SN</b></td>
</tr>
EOM
Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live. -- Damian Conway in "Perl Best Practices"
lesen: Wiki:Wie frage ich & perlintro Wiki:brian's Leitfaden für jedes Perl-Problem
renee
 2008-04-21 13:53
#108628 #108628
User since
2003-08-04
14371 Artikel
ModeratorIn
[Homepage] [default_avatar]
Mal ein paar Anmerkungen:

Aus
Code (perl): (dl )
1
2
3
4
5
6
7
8
opendir(DIRHANDLE, $path) or die "Directory not available";

while ( defined ($filename = readdir(DIRHANDLE)))
{
       @list=(@list,$filename);
}
@list=sort (@list);
@machinelist = grep {/.html/} @list;


kannst Du
Code (perl): (dl )
1
2
3
opendir(DIRHANDLE, $path) or die "Directory not available";
my @machinelist = grep{ /\.html/ } readdir(DIRHANDLE);
closedir DIRHANDLE;
machen.

Warum willst Du zweimal das gleiche Array haben?
Code (perl): (dl )
1
2
3
4
5
foreach $machine (@machinelist)
{
    $machine =~ s///;
    @allmachines=(@allmachines,$machine);
}


Das mit @allmachines kannst Du weglassen. @allmachines enthält die gleichen Elemente wie @machinelist, da Du die Elemente in @machinelist veränderst.

Außerdem solltest Du in Zukunft statt @allmachines=(@allmachines,$machine); einfach push @allmachines, $machine; schreiben.

Zusätzlich solltest Du Wiki:use strict verwenden...
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/
renee
 2008-04-21 14:01
#108629 #108629
User since
2003-08-04
14371 Artikel
ModeratorIn
[Homepage] [default_avatar]
Aus
Code (perl): (dl )
1
2
3
4
5
        foreach $try (@domains)
        {
                if ($try eq $dmn) {$ok=1};
        };
        if ($ok ne 1) {@domains=(@domains,$dmn)};


mach
Code (perl): (dl )
1
2
3
        unless( grep{ $_ eq $dmn }@domains ){
            push @domains, $dmn;
        }


In
Code (perl): (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
foreach $domain (@domains)
{
        @$domain=();
        foreach $machine (@allmachines)
        {
                @namepartsplit= split /\./, $machine;
                if ( $namepartsplit[1] eq $domain )
                {
                        @$domain=(@$domain,$machine);
                };
        };
@data=(@data,"start:$domain",@$domain,"end:$domain",);
};

steckt ein Fehler, denn Du verwendest $domain als Arrayreferenz, obwohl Du vorher nur Strings reingeschoben hast.

Später verwendest Du $domain für einen Stringvergleich. Da kann was nicht funktionieren...
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/
rioc
 2008-04-21 16:17
#108645 #108645
User since
2008-04-11
15 Artikel
BenutzerIn
[default_avatar]
hmm, ehrlich gesagt sehe ich das Problem nicht. (Programmier-Spezifisches Denken ist nicht meine Stärke, deswegen bin ich System-Techniker und nicht Appl.-Entwickler) ;)

@domains und @namepartsplit sind ja String-Arrays. Wieso kann ich dann nicht mit $domain einen Vergleich der Strings machen??
renee
 2008-04-21 16:37
#108647 #108647
User since
2003-08-04
14371 Artikel
ModeratorIn
[Homepage] [default_avatar]
Code (perl): (dl )
1
2
3
4
5
6
7
8
9
#!/usr/bin/perl

my $domain = 'unknown';

@$domain = ();
print $domain;

push @$domain, 'test';
print $domain;


Code: (dl )
1
2
3
rbaecker@test $ perl test.pl
1: unknown
2: unknown


Fällt Dir was auf?
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 3 >| >> 25 Einträge, 3 Seiten



View all threads created 2008-04-11 15:24.