Schrift
[thread]7641[/thread]

regex ups?



<< >> 7 Einträge, 1 Seite
oblivion
 2006-01-21 19:52
#62114 #62114
User since
2006-01-17
24 Artikel
BenutzerIn
[default_avatar]
hallo und schönen guten Abend,

ich sitze immer noch an dem lustigen Hardware-inventarisierungstool und komme mit regex nicht weiter.

ich würde gerne jeden Eintrag, der mir unter *nix beim Aufruf von lshal erscheint in einem hash speichern. soweit so gut, ich habe mir jetzt mal eine testdatei geschrieben die den gleichen aufbau hat,

also:

\n
text1
text11
text12
\n
text2
text21
text22
\n

usw.

nun wollte ich ein regex schreiben, das mir jeden eintrag zwischen den beiden leerzeilen in einem hash speichert. Ich habe jetzt schon längere Zeit mit der Dokumentation zu regEx verbracht, bekomme aber immer nur Unsinn raus.
Code: (dl )
1
2
3
4
5
6
7
8
9
10
#! /usr/bin/perl -w

open (FH,"lshal.txt") || die "Datei nicht gefunden";

while ($_=<FH>)
{
$_ = ~ /^$/;
print $_;
}
close(FH);


was mach ich denn falsch?

vielen Dank an Euch und nen schönen Abend


Gruß Oblivion\n\n

<!--EDIT|oblivion|1137866100-->
pKai
 2006-01-21 20:38
#62115 #62115
User since
2005-02-18
357 Artikel
BenutzerIn
[default_avatar]
Der Match-Operator in Perl heißt =~.
Wenn du da ein Leerzeichen reinpraktizierst, wird das ein Zuweisungs-Gleichheitszeichen gefolgt von einem binärem Negationsoperator (binär im Sinne von Binärzahl; der Operator selber ist unär ;)).
I sense a soul in search of answers.
renee
 2006-01-22 05:47
#62116 #62116
User since
2003-08-04
14371 Artikel
ModeratorIn
[Homepage] [default_avatar]
Ein paar allgemeine Anmerkungen:

*) Benutze in Deinem Skript am Besten Wiki:use strict;

*)
Code: (dl )
1
2
3
#! /usr/bin/perl -w

open (FH,"lshal.txt") || die "Datei nicht gefunden";


Verwende am besten das open mit 3 Parametern:
open(FH,"<","lshal.txt") or die "Datei nicht gefunden";.
Das "<" gibt an, dass die Datei gelesen wird.

Code: (dl )
1
2
while ($_=<FH>)
{

Die explizite Zuweisung an $_ brauchst Du nicht. Es reicht while(<FH>)

Code: (dl )
   $_ = ~ /^$/;


Der Fehler wurde schon oben genannt. Aber die Zeile ist auch ohne den Fehler wirkungslos. Wahrscheinlich wolltest Du die Zeile ueberspringen wenn es eine Leerzeile ist, oder? Dann muesste es
next if(/^$/); heissen.

Bei Dir hat es keine Auswirkungen wenn es eine Leerzeile ist.
Wenn man bei $_ testet, dann kann man das $_ =~ weglassen (man kann es aber auch hinschreiben, waere dann halt next if($_ =~ /^$/)).
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/
Dubu
 2006-01-22 15:06
#62117 #62117
User since
2003-08-04
2145 Artikel
ModeratorIn + EditorIn

user image
Ein guter Trick hier ist es, Perls Vorstellung davon zu aendern, was eine Zeile ist. Dafuer gibt es die Variable $/.

Nachdem ich mir gerade die Ausgabe von lshal angeschaut habe, kann ich mir vorstellen, wie man sie in einen Hash bekommen koennte. Hier ist ein Vorschlag:

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
#! /usr/bin/perl -w
use strict;
use warnings;

my %Entries;
my $LsHal = '/usr/bin/lshal';

open (LSHAL, '-|',  $LsHal) or die "could not start $LsHal: $!";

# "Paragraph Mode" - ein oder mehr Leerzeilen gelten als Trenner
$/ = "";

# Die Schleide geht jetzt ueber einzelne Absaetze
while (<LSHAL>) {
   # In einzelne Zeilen aufteilen
   my ($key, @lines) = split /\n/;

   # Das 'udi = ' am Anfang der ersten Zeile
   # und die Anfuehrungszeichen loeschen
   $key =~ s/^udi\s*=\s*'(.*)'/$1/;

   # Leerzeichen am Anfang der anderen Zeilen loeschen
   s/^\s+// for @lines;

   # Einen Untereintrag fuer jede Zeile anlegen, wobei
   # der Teil vor dem ' = ' als Schluessel, der Teil dahinter
   # als Wert genommen wird.
   my %subentries = map { split /\s*=\s*/, $_, 2 } @lines;

   # Untereintraege unter $key speichern
   $Entries{$key} = \%subentries;
}

# Testausgabe
use Data::Dumper;
print Dumper \%Entries;

exit 0;
\n\n

<!--EDIT|Dubu|1137935205-->
Gast Gast
 2006-01-23 10:14
#62118 #62118
wow Leute ihr seid super!!! vielen Dank für eure Hilfe ;-)))))
Strat
 2006-01-23 17:33
#62119 #62119
User since
2003-08-04
5246 Artikel
ModeratorIn
[Homepage] [default_avatar]
1. es kann gefaehrlich sein, den Inhalt von $/ zu aendern, wenn man noch weitere Dateien (oder aehnliches) einliest. Sicherer ist es, nur eine lokal gueltige Kopie von $/ zu veraendern, z.B.
Code: (dl )
1
2
3
4
5
6
7
8
open (LSHAL, .....) or die;
{ # Block
local $/ = "irgendwas";
while (<LSHAL>) {
...
} # while
} # Block
close (LSHAL);

dann ist die gueltigkeit von $/ nur auf den Block eingeschraenkt.

2. es kann gefaehrlich sein, while (<LSHAL>) zu verwenden, weil hier $_ kein Alias auf die Zeile ist (wie z.B. bei for(each), map/grep).
Code: (dl )
1
2
3
4
5
6
7
8
9
10
my $x = 30;
while (<STDIN>) {
print "Vorher: $_\n";
&Machwas();
print "Nachher: $_\n";
} # while
sub Machwas {
$_ = $x;
if (/0/) { print "Null drinnen\n"; }
}

besser mit einer expliziten Variable arbeiten: while (my $block = <LSHAL>) {
perl -le "s::*erlco'unaty.'.dk':e,y;*kn:ai;penmic;;print"
http://www.fabiani.net/
oblivion
 2006-01-24 19:28
#62120 #62120
User since
2006-01-17
24 Artikel
BenutzerIn
[default_avatar]
ok, habe deinen Rat befolgt. vielen Dank an Euch alle, dass ihr mir so weiterhelft!
<< >> 7 Einträge, 1 Seite



View all threads created 2006-01-21 19:52.