Perl wert aus einer datei auslesen

S

SilverICE

Jungspund
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
 
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! :)
Code:
#!/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
 
Code:
#!/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:

Code:
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.
 
btw.
@ RexEvel

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

Steve
 
@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
 
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
 
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

Code:
<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

Code:
#!/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

Code:
<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

Code:
<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.
 
Zuletzt bearbeitet:
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

Code:
#!/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
 
Zuletzt bearbeitet von einem Moderator:
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 für Module und auf Perldoc für Modulerklärungen und generelle Dokus immer alles zu finden was du benötigst!

ciao Exi
 
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?
 
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
 

Ähnliche Themen

Kernel Kaltstart / reboot?

Verzeichnis mit 1200 Dateien auf Verweise in Textdateien checken

sed in awk

Komplette Spalten aus Datei löschen.

Keine grafische Oberfläche (Debian Installation)

Zurück
Oben