Zum Inhalt springen

PERL und Regex :/


Empfohlene Beiträge

Hoi,

mich treiben Regex so richtig schön in den Wahnsinn atm.

Ich habe eine Datei deren Inhalt wie folgt aussieht:

"

akion-p4 IN A 191.100.1.268 ;PC4

;

njb-zkhv IN A 109.105.1.249 ;Mueller Notebook

;

"

etc.

Ich suche nun einen regulären Ausdruck der mir das Wort vor dem ersten Whitespace in eine Variable speichert (z.b. "akion-p4"). Dieser muss quasi zwingend variabel gehalten werden. Also die Namen sind nicht vorher bekannt und auch nicht immer gleich lang oder sowas.

Mein kümmerlicher Versuch sieht bisher so aus:


if (defined($ARGV[0] && $ARGV[1])){

		open(AHANDLE, "$ARGV[0]") || die "Datei kann nicht geoeffnet werden: ";

		open(XHANDLE, "$ARGV[1]") || die "Datei kann nicht geoeffnet werden: ";

		while ($zeile = <AHANDLE>) {

			#Wenn Zeile nicht mit Semikolon beginnt:

			if (!($zeile =~ m/^;/)) {

#ab hier wirds Schwachsinn

			    $zeile2 = $zeile;

				$string = "^.+\s+";

#comb wurde mir in nem tutorial vorgeschlagen funktioniert aber nicht?

				$name = $zeile2.comb(m/$string/);

			}


		}

	close(DHANDLE);


	}else{

		print "FEHLER: Notwendige Paramter nicht richtig uebergeben. Skript muss mit den Namen der beiden zu vergleichenden Files aufgerufen werden!\n"; 

	}

Fehlerausgabe: Undefined subroutine &main::comb called at ..... line 11.

Meine PERL Kenntnisse sind äußerst unterirdisch, allerdings soll die Aufgabe zwingend mit eben dieser Sprache erledigt werden. Der eigentliche Zweck des Skripts ist noch nicht erkennbar (2 Dateien vergleichen und fehlende aus der einen in der anderen löschen....).

Vielen Dank für Hilfestellungen/Ideen/Anregungen

M.

Bearbeitet von AgathoN
Link zu diesem Kommentar
Auf anderen Seiten teilen

$string =~ m/^(.+)\s/;  

In $1 ist dann der geklammerte Reg exp.

Ob .+ genauso "gierig" ist wie .* weiss ich nicht. Wenn ja, dann musst .+? nehmen.

(Wobei ich . nicht benutzen würde, wenn du weisst dass es nur Buchstaben/Zahlen/- sind, da tut es ein [\w-]).

comb kenn ich nicht und brauchst auch nicht. Und du kannst das alles gleich in der if-abfrage machen und musst nicht zweimal suchen.

Linktipp: http://search.cpan.org/dist/perl/pod/perlre.pod

Bearbeitet von bigvic
Link zu diesem Kommentar
Auf anderen Seiten teilen

hi,

leider ist mir nicht klar was du meinst und der link beeinhaltet nur das was ich bereits in 10 tabs nebeneinander auf habe hier.

if (!($zeile =~ m/^;/) & ($zeile =~ m/^[\w-]\s+/)) {

funktioniert nicht.

Alle Sachen die ich mit $1 ausprobiert habe führten zu einer Fehlermeldung das $1 nicht definiert wäre

:(

Link zu diesem Kommentar
Auf anderen Seiten teilen

C:\Programme\XAMPP webserver\xampp\htdocs\perl\csv vgl>perl vgl.plx private.1 su

bnet_1

new-pc-v IN A 192.168.1.10

tapelib IN A 192.168.1.33

fritz IN A 192.168.1.36

hisdbs IN A 192.168.1.38

ststel IN A 192.168.1.43 ;Telef.Notenabfrage

test-pc IN A 192.168.1.46 ;PC zum Testen

ull IN A 192.168.1.47 ;SUN 220R

rz-his IN A 192.168.1.49

hisdbs1 IN A 192.168.1.55

hisdbs2 IN A 192.168.1.56

hisdbs3 IN A 192.168.1.57

Quasi die 2.if wird nie erfüllt. Ergo muss noch etwas am Re falsch sein.

	#wenn Paramenter beim Aufruf vorhanden/uebergeben dann dateihandler oeffnen

	if (defined($ARGV[0] && $ARGV[1])){

		open(AHANDLE, "$ARGV[0]") || die "Datei kann nicht geoeffnet werden: ";

		open(XHANDLE, "$ARGV[1]") || die "Datei kann nicht geoeffnet werden: ";


		while ($zeile = <AHANDLE>) {

			#Wenn Zeile nicht mit Semikolon beginnt:

			if (!($zeile =~ m/^;/)) {

				if ($zeile =~ m/^([\w-])\s+/) {

					print $1;

				} else {

					print $zeile."\n";

				}

			}

		}

	close(DHANDLE);


	}else{

		print "FEHLER: Notwendige Paramter nicht richtig uebergeben. Skript muss mit den Namen der beiden zu vergleichenden Files aufgerufen werden!\n"; 

	}

Thx

edit: mit komplett deiner variante steht quasi nur da

C:\Programme\XAMPP webserver\xampp\htdocs\perl\csv vgl>perl vgl.plx private.1 su

bnet_1

Schade

Schade

Schade

Schade

Schade

Schade

Schade

Schade

Schade

Schade

Schade

Bearbeitet von AgathoN
Link zu diesem Kommentar
Auf anderen Seiten teilen

hallo vic,

muss leider doch noch mal nerven. :hells:

	print 'Datei 1: ' . $ARGV[0] ."\n";

	print 'Datei 2: ' . $ARGV[1];

	print "\n********************\n";


	#wenn Paramenter beim Aufruf vorhanden/uebergeben dann dateihandler oeffnen

	if (defined($ARGV[0] && $ARGV[1])){

		open(AHANDLE, "$ARGV[0]") || die "Datei kann nicht geoeffnet werden: ";

		open(XHANDLE, "$ARGV[1]") || die "Datei kann nicht geoeffnet werden: ";


		#Zaehlvariable

		$i=0;

		$u=0;

		#das File mit dem verglichen wird einlesen, interessanten Teil abtrennen und in Array speichern			

		while ($zeile = <XHANDLE>) {

			#Schneidet das erste "Wort" ab (erkannt wird es an dem folgenden Semikolon)

			if ($zeile =~ m/^([\w-]+);/) {

				@vgl[$i]=$1;

				$i++;

			}

		}


		#Testausgabe

		print "Elemente im Vergleichsarray : \n";

		my $vglstring = join(", ",@vgl);

		print $vglstring;

		print "\n********************\n";


		while ($zeile = <AHANDLE>) {

		#Schneidet das erste "Wort" ab (erkannt wird es an den folgenden Whitespaces)

			if ($zeile =~ m/^([\w-]+)\s+/) {

				if (grep($1 , @vgl)){

					print $zeile." Succes!\n";

				}

			} else {

				print "FAIL!\n";

			}

		}


	close(AHANDLE);

	close(XHANDLE);

	}else{

		print "FEHLER: Notwendige Paramter nicht richtig uebergeben. Skript muss mit den Namen der beiden zu vergleichenden Files aufgerufen werden!\n"; 

	}

...funktioniert eigentlich soweit. Jedoch wird z.b.

falschtest IN A 192.168.1.57

Succes!

FAIL!

ausgegeben. Ergo falschtest als true im Vergleich mit den im zum Vergleich heran gezogenem Array ausgewertet. Falschtest ist jedoch nicht im Array enthalten. Jedes Wort erfüllt quasi die Bedingung?! :/ Der Fehler muss entweder im Vergleich liegen (if ($zeile =~ m/^([\w-]+)\s+/) ) oder im grep.

Das Array (@vgl) funktioniert, ich lasse es mir ja testweise oben ausgeben...

Link zu diesem Kommentar
Auf anderen Seiten teilen

Da bin ich schon wieder. Brauchst dich nicht mit quälen...habe es jetzt mit foreach gelöst.

		while ($zeile = <AHANDLE>) {

		#Schneidet das erste "Wort" ab (erkannt wird es an den folgenden Whitespaces)

			if ($zeile =~ m/^([\w-]+)\s+/) {

				print "$1\n";

				$string=$1;

				foreach (@vgl) {

					push @vgl_erg, $zeile if $_ eq $string;

				}

			} else {

				print "FAIL!\n";

			}

		}

Warum es mit grep nicht geht ist mir zwar nicht ganz klar aber ist ja auch nebensächlich.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Dein Kommentar

Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.

Gast
Auf dieses Thema antworten...

×   Du hast formatierten Text eingefügt.   Formatierung wiederherstellen

  Nur 75 Emojis sind erlaubt.

×   Dein Link wurde automatisch eingebettet.   Einbetten rückgängig machen und als Link darstellen

×   Dein vorheriger Inhalt wurde wiederhergestellt.   Editor leeren

×   Du kannst Bilder nicht direkt einfügen. Lade Bilder hoch oder lade sie von einer URL.

Fachinformatiker.de, 2024 by SE Internet Services

fidelogo_small.png

Schicke uns eine Nachricht!

Fachinformatiker.de ist die größte IT-Community
rund um Ausbildung, Job, Weiterbildung für IT-Fachkräfte.

Fachinformatiker.de App

Download on the App Store
Get it on Google Play

Kontakt

Hier werben?
Oder sende eine E-Mail an

Social media u. feeds

Jobboard für Fachinformatiker und IT-Fachkräfte

×
×
  • Neu erstellen...