Mit Perlscript Teilstrings suchen!

Vom einfachen Programm zum fertigen Debian-Paket, Fragen rund um Programmiersprachen, Scripting und Lizenzierung.
Antworten
cs-flasher
Beiträge: 67
Registriert: 06.10.2002 15:01:34

Mit Perlscript Teilstrings suchen!

Beitrag von cs-flasher » 24.05.2005 10:27:45

Hallo,

ich habe folgendes Problem:

Ich lese in meinem Script eine Datei zeilenweise aus und suche in jeder Zeile nach zwei Suchbegriffen nämlich "atmport" und "elan". Sind diese beiden Begriffe vorhanden soll die Zeile NICHT in eine Datei geschrieben werden, falls die beiden Begriffe nicht vorhanden sind, soll die Zeile geschrieben werden.

Mein Script sieht folgendermaßen aus:

Code: Alles auswählen

print "\nPower-HUB und ES Konverter\n";
print "==========================\n\n";
print "Bitte geben Sie die Quelldatei an!\n";
chop($sourcefile = );
-e $sourcefile or print "Die Datei " . $sourcefile . "existiert nicht!";
open(EFILE, "<$sourcefile") or die "Kann Quelldatei nicht oeffnen!\n";

print "\nBitte geben Sie die Datei an, in der die konvertierten Daten speichert werden sollen!\n";
chop($destfile = );
open(AFILE, ">>$destfile");

while ($line = )
{
$pos = -1;
while (($pos = index($line, "atmport", $pos)) <= -1)
{
print AFILE $line;
$pos++;

}
$pos = -1;
while (($pos = index($line, "elan", $pos)) <= -1)
{
print AFILE $line;
$pos++;

}
}
close(AFILE);
close(EFILE);
exit 0
Leider funktioniert das nicht ganze nicht :-(
Das Script bleibt beim durchsuchen hängen und gibt immer nur die gleiche Zeile aus.

Hier mal die Datei, in der gesucht werden soll:

...............
00 00 0c 3e 64 55 89.0.17.1:49:atmport-49
00 00 0c 6e 0b 00 89.0.17.1:49:atmport-49
00 00 1c b0 a9 0b 89.0.17.1:49:atmport-49
00 00 1d 11 f8 51 89.0.17.1:1:Port_1
00 00 1d 15 81 6b 89.0.17.1:15:Port_15
00 00 1d 17 8d 11 89.0.17.1:2:Port_2
00 00 1d 18 51 40 89.0.17.1:49:atmport-49
00 00 1d 23 74 0f 89.0.17.1:16:Port_16
00 00 50 08 c4 ed 89.0.17.1:49:atmport-49
00 00 5e 00 01 01 89.0.17.1:49:atmport-49
00 00 74 7d 33 58 89.0.17.1:49:atmport-49
00 00 74 7e 77 64 89.0.17.1:49:atmport-49
00 00 74 82 cb 3c 89.0.17.1:49:atmport-49
00 00 74 8c 39 6d 89.0.17.1:49:atmport-49
00 00 74 8c 84 bf 89.0.17.1:49:atmport-49
00 00 74 8f 4a 89 89.0.17.1:49:atmport-49
00 00 74 90 09 0e 89.0.17.1:49:atmport-49
00 00 74 90 59 ff 89.0.17.1:49:atmport-49
00 00 74 91 40 42 89.0.17.1:49:atmport-49
00 00 85 2b 6d 48 89.0.17.1:49:atmport-49
................

Hat jemand eine Idee, wo der Fehler liegt?

Danke!

Gruß,

Andi

EDIT: [ code ] eingefuegt - blackm

gms
Beiträge: 7798
Registriert: 26.11.2004 20:08:38
Lizenz eigener Beiträge: MIT Lizenz

Beitrag von gms » 24.05.2005 10:48:30

ist doch ein einzeiler

Code: Alles auswählen

perl -ne ' print if $_!~/(atmport|elan)/; ' in.txt  >out.txt
das ist auch eine Endlosschleifen wenn "atmport" in dieser Zeile nicht vorkommt

Code: Alles auswählen

$pos = -1; 
while (($pos = index($line, "atmport", $pos)) <= -1) 
{ 
print AFILE $line; 
$pos++; 

} 
Gruß
gms

cs-flasher
Beiträge: 67
Registriert: 06.10.2002 15:01:34

Beitrag von cs-flasher » 24.05.2005 11:30:23

sorry, aber ich kann dieses perl einfach nicht, brauche aber schnell so ein script

Leider wird dieses script auf einer windows kiste ausgeführt

wie krieg ich diesen oneliner von dir in mein perlscript rein?

ich weiß nicht wie ich dem print if, die zeile $line übergeben soll!

Danke nochmals!

gms
Beiträge: 7798
Registriert: 26.11.2004 20:08:38
Lizenz eigener Beiträge: MIT Lizenz

Beitrag von gms » 24.05.2005 11:39:37

einfach deine äußere while-Schleife durch diese ersetzen:

Code: Alles auswählen

while {<EFILE>}
{
  $line=$_;
  print AFILE $line if  $line !~ /(atmport|elan)/;
}

Gruß
gms

cs-flasher
Beiträge: 67
Registriert: 06.10.2002 15:01:34

Beitrag von cs-flasher » 24.05.2005 14:43:06

Hallo,

jetzt bräuchte ich nochmal eure Hilfe! Und diesmal wirds schon komplizierter ;-)


Meine Liste enthält immer folgendes gleiche "Zeilenmuster"

.....
00 60 97 b2 8b fb 89.0.17.100:11:sec10 b11
.....

Diese Zeile wird in die Variable $line eingelesen.
Jetzt müsste ich den String allerdings aufteilen.

Und zwar die ersten 6 Hexadezimalpaare stellen eine MAC-Adresse dar.
Der Teilstring müsste dann in die Variable "var1" geschrieben werden und alle Leerzeichen durch Punkte ersetzt werden.
Also var1 = 00.60.97.b2.8b.fb

Die IP-Adresse bräuchte ich in var2
Also var2 = 89.0.17.100:11

Und ganz zum Schluss bräuchte ich noch den letzten Wert "b11" wobei dieser nicht auch nur zwei Zeichen haben kann.
Also var3 = b11

Hat da vielleicht noch jemand einen oneliner auf Lager?

Oder auch ein gutes Tutorial, wo erklärt wird, wie man diese Strings aufteilt wäre sehr hilfreich!

Nochmal vielen Dank!

Gruß,

Andi

gms
Beiträge: 7798
Registriert: 26.11.2004 20:08:38
Lizenz eigener Beiträge: MIT Lizenz

Beitrag von gms » 24.05.2005 15:10:02

nicht optimierter onliner:

Code: Alles auswählen

perl -ne '$line=$_; @vars=split(/ +/,$line); next if !defined $vars[6]; $vars[6]=~s/:.*$//; $var2=$vars[6]; $var3=$vars[7]; splice(@vars,6); $var1=join(".",@vars); print "ip=$var2 mac=$var1 var3=$var3\n";' in.txt


Gruß
gms

[matzi]
Beiträge: 16
Registriert: 20.05.2005 11:25:26
Wohnort: Weinheim
Kontaktdaten:

Beitrag von [matzi] » 24.05.2005 15:46:19

Oder vielleicht so:

Code: Alles auswählen

#!/usr/bin/perl

use strict;

my $infile = 'test.txt';

open(IN, '<', $infile) or die("Die Datei \"$infile\" konnte nicht zum lesen geoeffnet werden\n");

while(<IN>) {
    chomp($_);
    if ($_ =~ /^\s*([0-9a-f][0-9a-f]*\s+[0-9a-f][0-9a-f]*\s+[0-9a-f][0-9a-f]*\s+[0-9a-f][0-9a-f]*\s+[0-9a-f][0-9a-f]*\s+[0-9a-f][0-9a-f]*)\s+([0-9][0-9]*[0-9]*\.[0-9][0-9]*[0-9]*\.[0-9][0-9]*[0-9]*\.[0-9][0-9]*[0-9]*)\s*:\s*([0-9]+)\s*:\s*(.+)/i) {
	my ($var0, $var1, $var2, $var3) = ($1, $2, $3, $4);
	$var0 =~ s/ /./g;
	print("\"var0 = $var0\" \"var1 = $var1\" \"var2 = $var2\" \"var3 = $var3\"\n");
    }
}

cs-flasher
Beiträge: 67
Registriert: 06.10.2002 15:01:34

Beitrag von cs-flasher » 29.05.2005 12:14:47

Hallo,

jetzt habe ich noch zwei allerletzte Probleme und dann bin ich endlich fertig :)

1. Ich habe noch eine dritte Eingabedatei, sieht folgendermaßen aus:

................
BRENNER,89.13.11.84,00:11:43:BB:C0:63,1MAA,Microsoft Windows XP Professional
CCS01,89.13.10.227,000476460F90,koppitz,Microsoft Windows 2000 Professional
CCS01,89.10.72.82,unknown,koppitz,Microsoft Windows 2000 Professional
CDWRITER,89.10.6.47,0020480E27B6,nowatius,Microsoft Windows 2000 Professional
CDWRITER,89.10.81.85,unknown,nowatius,Microsoft Windows 2000 Professional
CDWRITER,89.12.2.210,unknown,nowatius,Microsoft Windows 2000 Professional
CG4000A2,-,-,RUEDIG_M,Microsoft Windows XP Professional
CG4000A2,-,-,RUEDIG_M,Microsoft Windows XP Professional
................

Jeder Wert pro Zeile wird durch ein Komma getrennt.
Ich würde diese Datei gerne zeilenweise einlesen lassen und diesen String dann so zerlegen, dass bei den Kommas immer der Schnittpunkt ist, also aus:

BRENNER,89.13.11.84,00:11:43:BB:C0:63,1MAA,Microsoft Windows XP Professional

wird:

var1 = BRENNER
var2 = 89.13.11.84
var3 = 00:11:43:BB:C0:63
var4 = 1MAA
var5 = Microsoft Windows XP Professional

Wichtig dabei wäre, dass die Werte die zwischen den Kommas stehen, nicht unbedingt immer dem selben Muster entsprechen, d.h. die Aufteilung müsste streng nach den Kommas geschehen!

2. var3 kann unterschiedliche Typen von Werten enthalten.
und zwar entweder "00:11:43:BB:C0:63" oder "0020480E27B6".

Falls var3 nach dem Muster "0020480E27B6" aufgebaut ist, soll sie nach "00:20:48:0E:27:B6" gewandelt werden.

Also wenn ihr das noch für mich hinkriegen würdet, bin ich euch ewig dankbar :) Den Rest krieg ich mittlerweile schon alleine hin :wink:

Gruß,

Andi

Benutzeravatar
Joghurt
Beiträge: 5244
Registriert: 30.01.2003 15:27:31
Wohnort: Hamburg
Kontaktdaten:

Beitrag von Joghurt » 29.05.2005 13:40:35

Code: Alles auswählen

@foo = split(',', $STRING);
print $foo[0];
print $foo[1];
print $foo[2];

[matzi]
Beiträge: 16
Registriert: 20.05.2005 11:25:26
Wohnort: Weinheim
Kontaktdaten:

Beitrag von [matzi] » 29.05.2005 13:42:11

Hallo cs-flasher,

So funktioniert's:

Code: Alles auswählen

#!/usr/bin/perl -w

use strict;

my $infile = 'test.txt';

open( IN, '<', $infile )
  or die("Die Datei \"$infile\" konnte nicht zum lesen geoeffnet werden\n");

while (<IN>) {
    chomp($_);
    my ( $var0, $var1, $var2, $var3 ) = split( /,/, $_, 4 );
    $var2 =~ s/([0-9a-f][0-9a-f])([0-9a-f][0-9a-f])([0-9a-f][0-9a-f])([0-9a-f][0-9a-f])([0-9a-f][0-9a-f])([0-9a-f][0-9a-f])/$1:$2:$3:$4:$5:$6/i;
    print("var0 = \"$var0\" var1 = \"$var1\" var2 = \"$var2\" var3 = \"$var3\"\n");
}

close(IN);
Gruß [matzi]

cs-flasher
Beiträge: 67
Registriert: 06.10.2002 15:01:34

Beitrag von cs-flasher » 30.05.2005 10:46:44

Hallo,

jetzt komm ich schon wieder mit einer Perlfrage an :wink:

Gibt es eine Möglichkeit, wenn ich zwei Strings mit equal vergleich, beim Vergleich nicht die Groß- und Kleinschreibung zu beachten.

Hintergrund der ganzen Angelegenheit:

Ich möchte zwei MAC-Adressen miteinander vergleichen,

Problem ist bei einer sind die Hexwerte A-F klein geschrieben und bei der zweiten klein :(

Danke!

Gruß,

flasher

Benutzeravatar
Joghurt
Beiträge: 5244
Registriert: 30.01.2003 15:27:31
Wohnort: Hamburg
Kontaktdaten:

Beitrag von Joghurt » 30.05.2005 10:54:17

Code: Alles auswählen

man perlre
Der magische Parameter heißt i!

Code: Alles auswählen

print "Nadel in Heuhaufen gefunden" if $Heuhaufen =~ m/nadel/i;

[matzi]
Beiträge: 16
Registriert: 20.05.2005 11:25:26
Wohnort: Weinheim
Kontaktdaten:

Beitrag von [matzi] » 30.05.2005 11:13:01

Code: Alles auswählen

$var0 = "TeSt";
$var1 = "test";

$var0 = lc($var0);    # in kleinbuchstaben wandeln
$var1 = lc($var1);    # in kleinbuchstaben wandeln

if ($var0 eq $var1) {
    print("JuHu\n");
}
PS: Schau dir doch mal diese Seite an:http://perl-seiten.privat.t-online.de/

Gruß
[matzi]

Antworten