PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Perl wert aus einer datei auslesen



SilverICE
09.02.2004, 11:05
hallo...

ich würde gerne mal wissen wie ich ein wert auslese..

ich habe eine datei. xml datei...

dort kommt z.B. drin vor

<x> 23 </x>
<y> 3 </y>

wie kann ich jetzt die zahlen in eine variable einlesen...
man müßte doch irgendwie sagen das variable= wert zwischen x und /x

danke

silver

ExRevel
09.02.2004, 15:05
Hi...

Ich habe dir mal schnel einen Source geschrieben an dem du nachvollziehen kannst wie es funktioniert! Er ist jetzt nicht besonder schön oder optimiert, vllt gibt es auch weitaus bessere Lösungen, aber er erfüllt die Aufgabe voll und ganz! :)


#!/usr/bin/perl

use strict;
use Tie::File;

my $file = "/home/timo/test.txt";

tie my @filebuffer, 'Tie::File', $file;

foreach my $line (@filebuffer){

$line =~ s/\s+|\t+//g;

if($line =~ /<x>/ or($line =~ /<y>/)){

my @array = split(/\W/, $line);

print "$array[2]\n";
}
}

Im zweiten $array element stehen deine Zahlen, mit denen du nun machen kannst was du willst. Vielleicht solltest du sie noch in globale Variablen verfrachten, damit du sie weiter bearbeiten kannst!

Bei Fragen stehe ich immer wieder zur Verfügung! :)

ciao Exi

Steve
09.02.2004, 18:07
#!/usr/bin/perl

use strict;

# Datei wird geöffnet (klar) :)
open( FH, "/home/stesch/textda") or die "$!\n";

undef $/; # $/ (Zeilentrenner wird auf undef gesetzt, dadurch wird die ganze Dat
ei auf einmal eingelesen
$_ = <FH>; # und an $_ zugewiesen

my ($x) = m/\<x\>\s(\d+)\s\<\/x\>/; # $_ wird dann in den Regex verwendet
my ($y) = m/\<y\>\s(\d+)\s\<\/y\>/; # und die Werte werden $x und $y zugewiesen

print "$x.... $y\n"; # Werte ausgeben
close FH; # Filehandle schließen


noch ne Erklärung zu den Regex:



m/ # Anfang
\<x\> # match auf <x>, < und > werden mit \ escaped
\s # ein einzelner White space
(\d+) # match mindest 1 Ziffern (Quantifier +)
\s\ # Whitespace
<\/x\> # s.o.
/x; # Ende des Regex, x entfernt leerzeichen in Kommentare


Steve

PS ich hoffe die Formatierung ist ordentlich.

Steve
09.02.2004, 18:12
btw.
@ RexEvel

hat das einen besonderen Grund, dass du nicht open benutzt?

Steve

ExRevel
09.02.2004, 18:30
@Steve... Naja eigentlich hat es keinen besonderen Grund, Tie is komfortabel und kurz, das gefällt mir und da es bei jeder Perlversion als Standardmodul dabei is greif ich gerne drauf zurück, was nicht bedeutet das ich nie open nutze! :)

ciao Exi

SilverICE
10.02.2004, 07:35
Hallo

Danke ihr habt mir beide geholfen...

ich stecke bei Perl noch in den Kinderschuh´n deshalb ist es bei solch einer sache immer gut es zu verstehen und nicht nur zu kopieren..

also danke euch beiden, ich werde mich jetzt mal an die arbeit machen und eure scripte ausprobieren..

Gruß Silver

SilverICE
10.02.2004, 08:31
hallo nochmal

so habe mir beide mal angeschaut.. und wieder ne frage

ExRevel benutz arrays was in meinem fall nich ganz so die gute lösung ist.. werde aber sicher auch noch arrays benutzen..

ich mische eure hinweise zusammen ;)

my ($x) = m/\<x\>\s(\d+)\s\<\/x\>/; # $_ wird dann in den Regex verwendet
my ($y) = m/\<y\>\s(\d+)\s\<\/y\>/; # und die Werte werden $x und $y zugewiesen

ok was macht m/ und (/d+)? \s\ nimmt wohl die leerzeichen raus wenn ich mich nicht irre.. sagt mir bitte wenn ich falsch liege..

mein problem ist was ist wenn zwischen

<x> 192.168.0.1 </x>

steht oder wert_zahl (unterstrich... sonderzeichen)

cu

hoffe auf schnell antwort

--

hi :) habe gelesen das man es mit XML:SimpleObject auch auslesen kann.. hab jetzt schon viel gegoogelt aber ich versteh es nicht :(

---
so hallo hallo ;)

hab jetzt etwas gefunden

nehmen wir an wir haben folgenden inhalt der xml file


<NODE>
<HOST NAME="q9j2k">
<MODEL> none </MODEL>
<OS_VERSION> Linux 2.4.18-64GB-SMP </OS_VERSION>
<LANGUAGE> en_US </LANGUAGE> <!-- Ermittlung der Sprache z.B. fuer win Deutsch= 1031 Englisch= 1033 -->
<CPU_NAME> GenuineIntel </CPU_NAME>
<CPU_CAPTION> PentiumIII(Cascades) </CPU_CAPTION> <!-- Ermittlung der zugehoerigen Familie der CPU -->
<CPU> 2 </CPU> <!-- Ermittlung von der Anzahl der CPU -->
<CPUSPEED> 701.636 </CPUSPEED>
<L2_CACHESIZE> 1024 </L2_CAHCESIZE>
<DISKDRIVESIZE>
<SIZE>2.8G</SIZE>
<SIZE>101M</SIZE>
<SIZE>5.5G</SIZE>
<SIZE>38G</SIZE>
</DISKDRIVESIZE>
<SYSTEMSERIAL_NR> none </SYSTEMSERIAL_NR>
<FIBRECHANNEL> none </FIBRECHANNEL> <!-- Ermittelt die Anzahl der Fibrechannel`s -->>
<MEMORY> 2069356 </MEMORY>
<NETMODUL> e100 </NETMODUL> <!-- Ermittliung der Netzwerkmodule -->
<NET_IP> <!-- Ermittlung der IP`s -->
<IP> eth0 164.20.111.32 </IP>
</NET_IP>
<NET_VIP> <!-- Ermittlung der virtuellen IP`s
<VIP> </VIP>
</NET_VIP>
</HOST>
</NODE>

wenn ich jetzt folgendes script anwende


#!/usr/bin/perl
use XML::Parser;
my $zeiger = new XML::Parser ();

$zeiger->setHandlers (Start => \&anfang,End => \&ende,Char=>\&inhalt );

$zeiger->parsefile ("test.xml");

sub anfang
{
$wert_des_zeigers = shift;
$starttag= shift;
print "<$starttag>";
print "\n";
}
sub ende
{
($wert_des_zeigers,$endtag) = @_;
print "</$endtag>\n";
}
sub inhalt
{
($wert_des_zeigers,$inhalt)=@_;
print " $inhalt";
}
habe ich folgende ausgabe


<NODE>

<HOST>

<MODEL>
none </MODEL>

<OS_VERSION>
Linux 2.4.18-64GB-SMP </OS_VERSION>

<LANGUAGE>
en_US </LANGUAGE>

<CPU_NAME>
GenuineIntel </CPU_NAME>

<CPU_CAPTION>
PentiumIII(Cascades) </CPU_CAPTION>

<CPU>
2 </CPU>

<CPUSPEED>
701.636 </CPUSPEED>

<L2_CACHESIZE>

hier bricht er wegen einem fehler ab.. aber das ist jetzt erst mal egal...

so das problem ist jetzt das ich diesen Inhalt in einer variablen brauche am besten der name des Anfangtags also bei


<CPUSPEED>
701.636 </CPUSPEED>

soll er die variable CPUSPEED mit dem wert 701.636 haben ( CPUSPEED=701.636)

so genau das brauche ich hoffe ihr könnt mir helfen...

p.s. ich rache hier schon .. bekomme anscheint nicht mal leichte sachen hin.

Steve
10.02.2004, 16:34
ok was macht m/ und (/d+)? \s\ nimmt wohl die leerzeichen raus wenn ich mich nicht irre.. sagt mir bitte wenn ich falsch liege..

da steht ne genaue Erklärung von der Regex.

Wenn du eine gesamte XMl-Datei parsen willt, dann nimm doch ein fach XML::Simple.
http://search.cpan.org/~grantm/XML-Simple-2.09/lib/XML/Simple.pm



#!/usr/bin/perl

use XML::Simple;
use Data::Dumper;

my $xml = XML::Simple->new;
my $hashref = $xml->XMLin("test.xml");

print $hashref->{'HOST'}->{'CPU_NAME'}, "\n";

print Dumper($hashref);


Mit Data::Dumper kann man sich einfach die Struktur seiner Datenstruktur angucken. Ein Beispiel für den Zugriff hast du auch.

Steve

ExRevel
10.02.2004, 17:11
Steve hat mal wieder völlig recht! :) Ich würde wenn es um Perlerklärungen geht nur äusserst selten googln. Du kannst dir sicher sein auf CPAN (http://www.cpan.org) für Module und auf Perldoc (http://www.perldoc.com) für Modulerklärungen und generelle Dokus immer alles zu finden was du benötigst!

ciao Exi

SilverICE
11.02.2004, 13:50
hi..

danke für die antworten..

ich werde mich morgen mal ran setzen uns es weiter versuchen...

my $xml = XML::Simple->new;
my $hashref = $xml->XMLin("test.xml");

print $hashref->{'HOST'}->{'CPU_NAME'}, "\n";

sehe ich das richtig das ich mit host die warible benenne und der wert cpuname ist?

ExRevel
11.02.2004, 15:37
Naja, HOST ist der Schlüssel des hashes in diesem Fall die Referenz auf ein Hash, deswegen auch die Schreibweise mit "->" auf den Schlüssel und auch CPU_NAME ist ein schlüssel, dessen Wert in deinem Falle 'GenuineIntel' sein dürfte. Das was mit dem Schlüssel CPU_NAME verknüpft ist nach dem Key-Value-Prinzip, das ist dein Wert.
Der Schlüssel HOST enthält halt die Schlüssel wie sie in deiner xmlfile auch durch einrückung und <> gekennzeichnet sind, MODEL, CPU_NAME, LANGUAGE...

Schau es dir einfach mal mit DataDumper...

ciao Exi