Zeilen mit IP finden die auf IP-Range passen

Zeilen mit IP finden die auf IP-Range passen

am 17.05.2007 15:50:41 von Peter Velan

Hallo,

vermutlich habe ich nur nicht den richtigen Ansatz, vielleicht kann mich
jemand schubsen ;-)

Gegeben eine Menge von Logfiles mit einzelnen IP-Adressen, alle in
klassischer "dotted quad"-Form (wegen Eindeutigkeit umrahmt von eckigen
Klammern und jeweils einem Blank davor und dahinter).
- Beispiel: " [123.129.36.5] "

Ich will alle Zeilen herausholen, in denen eine IP vorkommt, die in
einen vorgegeben Bereich passt
- Beispiel: von = 123.128.64.0 - 123.129.127.255

Bisher mach ich das mit pcregrep und manuell erstellter regexp. Bei
"einfachen" IP-Bereichen ist so eine regexp schnell zusammengezimmert,
aber wenn der Bereich so doof wie im obigen Beispiel ist, wird es
ziemlich nervig :-( Selbst wenn mann entsprechende Vereinfachungen macht
(hier z.B., dass das 4. Byte einfach als "\d{1,3}" angenommen wird), ist
das anstrengend:

" \[123\.12(8\.([0-5]\d|6[0-3])|9\.(\d|\d\d|1[01]\d|2[0-7))\.\ d{1,3}\] "

Ich suche also ein Modul oder eine Funktion, die aus "von-IP-Quad" und
"bis-IP-Quad" die passende regexp liefert, also (hier mit meinen
Beispielwerten gefüttert):

sub mydream( '123.128.64.0', '123.129.127.255' ) {
return
" \[123\.12(8\.([0-5]\d|6[0-3])|9\.(\d|\d\d|1[01]\d|2[0-7))\.\ d{1,3}\] "
;
}

Gibt es da was Fertiges (Modul, Funktion)?

Danke,
Peter

Re: Zeilen mit IP finden die auf IP-Range passen

am 17.05.2007 19:34:40 von Christian Kirsch

Peter Velan schrieb:
> Hallo,
>
> vermutlich habe ich nur nicht den richtigen Ansatz, vielleicht kann mich
> jemand schubsen ;-)
>
> Gegeben eine Menge von Logfiles mit einzelnen IP-Adressen, alle in
> klassischer "dotted quad"-Form (wegen Eindeutigkeit umrahmt von eckigen
> Klammern und jeweils einem Blank davor und dahinter).
> - Beispiel: " [123.129.36.5] "
>
> Ich will alle Zeilen herausholen, in denen eine IP vorkommt, die in
> einen vorgegeben Bereich passt
> - Beispiel: von = 123.128.64.0 - 123.129.127.255
>
> Bisher mach ich das mit pcregrep und manuell erstellter regexp. Bei
> "einfachen" IP-Bereichen ist so eine regexp schnell zusammengezimmert,
> aber wenn der Bereich so doof wie im obigen Beispiel ist, wird es
> ziemlich nervig :-( Selbst wenn mann entsprechende Vereinfachungen macht
> (hier z.B., dass das 4. Byte einfach als "\d{1,3}" angenommen wird), ist
> das anstrengend:
>
> " \[123\.12(8\.([0-5]\d|6[0-3])|9\.(\d|\d\d|1[01]\d|2[0-7))\.\ d{1,3}\] "
>
> Ich suche also ein Modul oder eine Funktion, die aus "von-IP-Quad" und
> "bis-IP-Quad" die passende regexp liefert, also (hier mit meinen
> Beispielwerten gefüttert):
>
> sub mydream( '123.128.64.0', '123.129.127.255' ) {
> return
> " \[123\.12(8\.([0-5]\d|6[0-3])|9\.(\d|\d\d|1[01]\d|2[0-7))\.\ d{1,3}\] "
> ;
> }
>

Eine IP-Adresse ist doch nichts weiter als eine Zahl. Warum also
wandelst Du nicht die Darstellung a.b.c.d in eben diese Zahl und
vergleichst dann? Das dürfte deutlich simpler sein. Idee:

$re = qr/(\d+)\.(\d+)\.(d+)\.(\d+)/;
$IP1 =~ $re;
$IP1_num = $4 + (128 * ($3 + (128 * ($2 + (128 * $1))));
$IP2 =~ $re;
$IP2_num = $4 + (128 * ($3 + (128 * ($2 + (128 * $1))));

# dasselbe für die fragliche $IP
# und dann ...

return $IP >= $IP1 && $IP <= $IP2

Disclaimer: Weder habe ich das getestet noch glaube ich, dass das die
beste Methode ist. Aber REs eignen sich eben nicht für jede Aufgabe -
besser als sich mit denen die Finger zu brechen, dürfte das hier schon sein.

Re: Zeilen mit IP finden die auf IP-Range passen

am 17.05.2007 21:09:55 von Christian Winter

Christian Kirsch schrieb:
> Eine IP-Adresse ist doch nichts weiter als eine Zahl. Warum also
> wandelst Du nicht die Darstellung a.b.c.d in eben diese Zahl und
> vergleichst dann? Das dürfte deutlich simpler sein. Idee:
>
> $re = qr/(\d+)\.(\d+)\.(d+)\.(\d+)/;
> $IP1 =~ $re;
> $IP1_num = $4 + (128 * ($3 + (128 * ($2 + (128 * $1))));
^^^ ^^^ ^^^
*hüstel* 256 bitte.

-Christian

Re: Zeilen mit IP finden die auf IP-Range passen

am 17.05.2007 22:00:02 von hjp-usenet2

On 2007-05-17 17:34, Christian Kirsch wrote:
> Peter Velan schrieb:
>> vermutlich habe ich nur nicht den richtigen Ansatz, vielleicht kann mich
>> jemand schubsen ;-)
>>
>> Gegeben eine Menge von Logfiles mit einzelnen IP-Adressen, alle in
>> klassischer "dotted quad"-Form (wegen Eindeutigkeit umrahmt von eckigen
>> Klammern und jeweils einem Blank davor und dahinter).
>> - Beispiel: " [123.129.36.5] "
>>
>> Ich will alle Zeilen herausholen, in denen eine IP vorkommt, die in
>> einen vorgegeben Bereich passt
>> - Beispiel: von = 123.128.64.0 - 123.129.127.255
>>
[...]
>>
>> Ich suche also ein Modul oder eine Funktion, die aus "von-IP-Quad" und
>> "bis-IP-Quad" die passende regexp liefert, also (hier mit meinen
>> Beispielwerten gefüttert):
>>
>> sub mydream( '123.128.64.0', '123.129.127.255' ) {

Was ist denn das für eine Syntax?

>> return
>> " \[123\.12(8\.([0-5]\d|6[0-3])|9\.(\d|\d\d|1[01]\d|2[0-7))\.\ d{1,3}\] "
>> ;
>> }
>>
>
> Eine IP-Adresse ist doch nichts weiter als eine Zahl.

Oder eine Folge von 4 Bytes.

> Warum also wandelst Du nicht die Darstellung a.b.c.d in eben diese
> Zahl und vergleichst dann? Das dürfte deutlich simpler sein. Idee:
>
> $re = qr/(\d+)\.(\d+)\.(d+)\.(\d+)/;
> $IP1 =~ $re;
> $IP1_num = $4 + (128 * ($3 + (128 * ($2 + (128 * $1))));

Der Faktor muss natürlich 256 sein, nicht 128.

Auf die 4-Byte-Darstellung kommt man z.B. so:

my $s = ' [143.130.50.123] ';

my $ip = pack('C4', $s =~ m/(\d+)\.(\d+)\.(\d+)\.(\d+)/);

oder auch mit

use Socket;

my $ip = inet_aton($s =~ m/(\d+\.\d+\.\d+\.\d+)/);

Vergleichen kann man dann einfach mit den String-Vergleichsoperatoren,
auch Bit-Operationen (z.B. für Masks) funktionieren.

hp


--
_ | Peter J. Holzer | I know I'd be respectful of a pirate
|_|_) | Sysadmin WSR | with an emu on his shoulder.
| | | hjp@hjp.at |
__/ | http://www.hjp.at/ | -- Sam in "Freefall"

Re: Zeilen mit IP finden die auf IP-Range passen

am 18.05.2007 10:37:20 von Peter Velan

am 17.05.2007 22:00 schrieb Peter J. Holzer:
> On 2007-05-17 17:34, Christian Kirsch wrote:
>> Peter Velan schrieb:
>>> - Beispiel: " [123.129.36.5] "
>>> - Beispiel: von = 123.128.64.0 - 123.129.127.255
>>>
>>> Ich suche also ein Modul oder eine Funktion, die aus "von-IP-Quad" und
>>> "bis-IP-Quad" die passende regexp liefert, also (hier mit meinen
>>> Beispielwerten gefüttert):
>>>
>>> sub mydream( '123.128.64.0', '123.129.127.255' ) {
>
> Was ist denn das für eine Syntax?

Ja, ist doof! (Hatte kurz vor dem Posting eine Affäre mit Madam PHP)

>>> " \[123\.12(8\.([0-5]\d|6[0-3])|9\.(\d|\d\d|1[01]\d|2[0-7))\.\ d{1,3}\] "
>>
>> Eine IP-Adresse ist doch nichts weiter als eine Zahl.

das weiß ich

> Oder eine Folge von 4 Bytes.

auch das ist mir bekannt

>> Warum also wandelst Du nicht die Darstellung a.b.c.d in eben diese
>> Zahl und vergleichst dann?

Weil ich dann mehrere hundert Logfiles durch Perl stopfen müsste. Mein
Ansatz war bisher: Grase die Logs mit pcregrep und passendem Muster ab.

>> Das dürfte deutlich simpler sein. Idee:
>>
>> $re = qr/(\d+)\.(\d+)\.(d+)\.(\d+)/;
>> $IP1 =~ $re;
>> $IP1_num = $4 + (128 * ($3 + (128 * ($2 + (128 * $1))));
>
> Der Faktor muss natürlich 256 sein, nicht 128.
>
> Auf die 4-Byte-Darstellung kommt man z.B. so:
>
> my $s = ' [143.130.50.123] ';
>
> my $ip = pack('C4', $s =~ m/(\d+)\.(\d+)\.(\d+)\.(\d+)/);
>
> oder auch mit
>
> use Socket;
>
> my $ip = inet_aton($s =~ m/(\d+\.\d+\.\d+\.\d+)/);
>
> Vergleichen kann man dann einfach mit den String-Vergleichsoperatoren,
> auch Bit-Operationen (z.B. für Masks) funktionieren.

Danke alle für die Schubser, werde mir das genauer zu Gemüte führen.
Vielleicht ist der Ansatz alles in Perl zu erledigen gar nicht so viel
langsamer als der von mir ins Auge gefasste Bash/Perl/pcregrep-Mischmasch:

#!/bin/bash

antwort=`./perlskript $1 $2`;
#
# obiges perlskript erzeugt aus den beiden Argumenten
# 123.128.64.0 (= $1) und 123.129.127.255 (= $2)
# antwort=" \[123\.12(8\.([0-5]\d|6[0-3])|9\. usw."

# dann mit pcregrep alle logs* abklappern und
# matchende Zeilen auf stdout listen:

cat /var/log/logs* | pcregrep -- "$antwort"

Gruß,
Peter

Re: Zeilen mit IP finden die auf IP-Range passen

am 18.05.2007 18:09:49 von hjp-usenet2

On 2007-05-18 08:37, Peter Velan wrote:
> Danke alle für die Schubser, werde mir das genauer zu Gemüte führen.
> Vielleicht ist der Ansatz alles in Perl zu erledigen gar nicht so viel
> langsamer als der von mir ins Auge gefasste Bash/Perl/pcregrep-Mischmasch:

Ich kenne die Implementation von pcregrep nicht, aber so rein
prinzipiell sehe ich keinen Grund, warum das deutlich schneller als Perl
sein sollte (die Regex-Engine ist wahrscheinlich sehr ähnlich, wenn
nicht sogar die gleiche, und viel mehr als Regexes matchen tut das ja
nicht).

Komplexe Regexes (vor allem, wenn Backtracking notwendig ist), können
recht langsam werden, da gewinnt man unter Umständen mit einer scheinbar
umständlicheren Methode sogar Performance.

hp


--
_ | Peter J. Holzer | I know I'd be respectful of a pirate
|_|_) | Sysadmin WSR | with an emu on his shoulder.
| | | hjp@hjp.at |
__/ | http://www.hjp.at/ | -- Sam in "Freefall"

Re: Zeilen mit IP finden die auf IP-Range passen

am 19.05.2007 12:28:08 von Peter Velan

am 18.05.2007 18:09 schrieb Peter J. Holzer:
> On 2007-05-18 08:37, Peter Velan wrote:
>> Danke alle für die Schubser, werde mir das genauer zu Gemüte führen.
>> Vielleicht ist der Ansatz alles in Perl zu erledigen gar nicht so viel
>> langsamer als der von mir ins Auge gefasste Bash/Perl/pcregrep-Mischmasch:
>
> Ich kenne die Implementation von pcregrep nicht, aber so rein
> prinzipiell sehe ich keinen Grund, warum das deutlich schneller als Perl
> sein sollte (die Regex-Engine ist wahrscheinlich sehr ähnlich, wenn
> nicht sogar die gleiche, und viel mehr als Regexes matchen tut das ja
> nicht).

Vermutlich richtig: pcregrep wird beim Matchen nicht schneller sein als
Perl. Ich verwende pcregrep als Ersatz für den "normalen" (e)grep, weil
ich zu den reguläre Ausdrücken über Perl gefunden habe und mir diese
Syntax vertrauter ist.

Das "reine" Perl-Verfahren erscheint mit aber doch erheblich
aufwendiger, als mein ursprünglicher Grundansatz: aus gegebener IP-Range
passendes reguläres Muster erzeugen (was von mir aus auch ein
grep-Muster sein könnte) und dann

# (pcr)egrep -- $muster /var/meine-logs*

zu verwenden. Der Ansatz, den mir hier alle vorgeschlagen haben,
erfordert aber:

a) einlesen einer Log-Zeile
b) prüfen ob " \[(.*?)\] " in Zeile vorkommt
c) wenn ja, IP-Quad "(.*?)" in Zahl wandeln
d) prüfen ob Zahl innerhalb des gewünschten Bereiches
e) Zeile listen wenn innerhalb

Da b) und c) für Millionen von Zeilen notwendig ist, kann ich mir nicht
vorstellen, dass das Verfahren einigermaßen flott funktionieren würde.
Aber ich kann mich da natürlich täuschen.

> Komplexe Regexes (vor allem, wenn Backtracking notwendig ist), können
> recht langsam werden, da gewinnt man unter Umständen mit einer scheinbar
> umständlicheren Methode sogar Performance.

Backtracking kommt hier nicht vor. Eine Performancesteigerung -
jedenfalls nicht beim Matchen - ist hier auch nicht notwendig. Meine "zu
Fuß"-Methode liefert mir in akzeptabler Zeit die Ergebnisse. Ich suchte
nach einer Möglichkeit die manuelle (und manchmal ziemlich aufwendige)
Suchmustererstellung zu automatisieren.

Gruß und schönes Wochende,
Peter

Re: Zeilen mit IP finden die auf IP-Range passen

am 19.05.2007 13:51:58 von Frank Seitz

Peter Velan wrote:

> Der Ansatz, den mir hier alle vorgeschlagen haben,
> erfordert aber:
>
> a) einlesen einer Log-Zeile
> b) prüfen ob " \[(.*?)\] " in Zeile vorkommt
> c) wenn ja, IP-Quad "(.*?)" in Zahl wandeln
> d) prüfen ob Zahl innerhalb des gewünschten Bereiches
> e) Zeile listen wenn innerhalb
>
> Da b) und c) für Millionen von Zeilen notwendig ist, kann ich mir nicht
> vorstellen, dass das Verfahren einigermaßen flott funktionieren würde.
> Aber ich kann mich da natürlich täuschen.

Da täuscht Du Dich bestimmt. Der (gefühlte) Aufand Deiner
Pattern-Matches ist bei mir höher.

>>Komplexe Regexes (vor allem, wenn Backtracking notwendig ist), können
>>recht langsam werden, da gewinnt man unter Umständen mit einer scheinbar
>>umständlicheren Methode sogar Performance.
>
> Backtracking kommt hier nicht vor.

Backtracking kommt bei Regexes zwangsläufig vor.

> Eine Performancesteigerung -
> jedenfalls nicht beim Matchen - ist hier auch nicht notwendig. Meine "zu
> Fuß"-Methode liefert mir in akzeptabler Zeit die Ergebnisse. Ich suchte
> nach einer Möglichkeit die manuelle (und manchmal ziemlich aufwendige)
> Suchmustererstellung zu automatisieren.

Dann sollte der geniale Vorschlag, die IP-Adressen in Zahlen
umzurechnen und die zu vergleichen, Dich doch eigentlich überzeugen.

Grüße
Frank
--
Dipl.-Inform. Frank Seitz; http://www.fseitz.de/
Anwendungen für Ihr Internet und Intranet
Tel: 04103/180301; Fax: -02; Industriestr. 31, 22880 Wedel

Re: Zeilen mit IP finden die auf IP-Range passen

am 19.05.2007 14:12:45 von Moritz Lenz

This is an OpenPGP/MIME signed message (RFC 2440 and 3156)
--------------enig60C54175E4DA1BBC72F3C653
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

Hallo,

Frank Seitz wrote:
> Peter Velan wrote:
>>> Komplexe Regexes (vor allem, wenn Backtracking notwendig ist), kö=
nnen
>>> recht langsam werden, da gewinnt man unter Umständen mit einer s=
cheinbar
>>> umständlicheren Methode sogar Performance.
>> Backtracking kommt hier nicht vor.
>=20
> Backtracking kommt bei Regexes zwangsläufig vor.

Bei Perl-Regexes schon, bei _regulären_ ausdrücken nicht. Wenn =
man also
keine keine Features verwendet, die über reguläre Audrücke=
herausgehen,
kann man auch eine nicht-backtracking-Implementierung verwenden.
Bleadperl bietet ja auch die Möglichkeit, unterschiedliche Regex-Eng=
ines
zu verwenden, da könnte man dann sowas verwenden.

Aber so langsam werden wir wohl off-topic ;-)

Grüße,
Moritz


--=20
Moritz Lenz
http://perl-6.de/ http://moritz.faui2k3.org/


--------------enig60C54175E4DA1BBC72F3C653
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: OpenPGP digital signature
Content-Disposition: attachment; filename="signature.asc"

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iD8DBQFGTunCAAkekJBI0yIRAj68AKC5Uer9C9sx38lvr0+y9aPXAxYggwCd FXpM
prHRNO45HxOMpecllMT4Tac=
=/SN0
-----END PGP SIGNATURE-----

--------------enig60C54175E4DA1BBC72F3C653--

Re: Zeilen mit IP finden die auf IP-Range passen

am 19.05.2007 14:44:29 von Frank Seitz

Moritz Lenz wrote:
> Frank Seitz wrote:
>>Peter Velan wrote:
>>>
>>>Backtracking kommt hier nicht vor.
>>
>>Backtracking kommt bei Regexes zwangsläufig vor.
>
> Bei Perl-Regexes schon, bei _regulären_ ausdrücken nicht.

Das hängt wohl (wie Du selbst auch sagst) von der Regex-Engine ab.
Der NFA von Perl backtrackt auch bei den klassischen regulären
Ausdrücken der Theoretischen Informatik, meine ich (natürlich
nicht in jedem Einzelfall, aber im Allgemeinen).

Grüße
Frank
--
Dipl.-Inform. Frank Seitz; http://www.fseitz.de/
Anwendungen für Ihr Internet und Intranet
Tel: 04103/180301; Fax: -02; Industriestr. 31, 22880 Wedel

Re: Zeilen mit IP finden die auf IP-Range passen

am 19.05.2007 17:11:47 von hjp-usenet2

On 2007-05-19 11:51, Frank Seitz wrote:
> Peter Velan wrote:
>> Der Ansatz, den mir hier alle vorgeschlagen haben,
>> erfordert aber:
>>
>> a) einlesen einer Log-Zeile
>> b) prüfen ob " \[(.*?)\] " in Zeile vorkommt
>> c) wenn ja, IP-Quad "(.*?)" in Zahl wandeln
>> d) prüfen ob Zahl innerhalb des gewünschten Bereiches
>> e) Zeile listen wenn innerhalb
>>
>> Da b) und c) für Millionen von Zeilen notwendig ist, kann ich mir nicht
>> vorstellen, dass das Verfahren einigermaßen flott funktionieren würde.

b) ist auch bei der Regex-Methode für Millionen von Zeilen notwendig.
D.h. die Frage ist, was ist schneller:

1) Eine komplexe Regex matchen

2) Eine einfache Regex matchen und anschließend eine Zahl (einen String)
daraus berechnen und vergleichen.

Das hängt davon ab, wie komplex die Regex ist.

>> Aber ich kann mich da natürlich täuschen.
>
> Da täuscht Du Dich bestimmt. Der (gefühlte) Aufand Deiner
> Pattern-Matches ist bei mir höher.

Das Gefühl kann täuschen. Regexes sind hier[0] tatsächlich deutlich
schneller (3.5 mal schneller als die von mir vorgeschlagene
inet_aton-Methode, fast 5 mal schneller als die Umwandlung in Zahlen),
bei Verwendung von reinem Perl. pcregrep ist noch einmal um 50%
schneller als perl 5.8.8.

>> Eine Performancesteigerung - jedenfalls nicht beim Matchen - ist hier
>> auch nicht notwendig. Meine "zu Fuß"-Methode liefert mir in
>> akzeptabler Zeit die Ergebnisse. Ich suchte nach einer Möglichkeit
>> die manuelle (und manchmal ziemlich aufwendige) Suchmustererstellung
>> zu automatisieren.
>
> Dann sollte der geniale Vorschlag, die IP-Adressen in Zahlen
> umzurechnen und die zu vergleichen, Dich doch eigentlich überzeugen.

Yep. Ob die Suche pro GB jetzt 8 oder 30 Sekunden dauert, ist
einigermaßen egal, im Vergleich zu den 10 Minuten, die man damit
verbringt, den Fehler in der Regex zu suchen (die Regex des OP enthielt
zwei Fehler: Der erste war ziemlich offensichtlich, der zweite besser
versteckt und ist mir nur deshalb aufgefallen, weil die Regex nur 2479
Ergebnisse geliefert hat statt 2577).

hp

[0] Auszüge aus qpsmtpd-Logs. Verwendet wurden nur Zeilen, die
IP-Adressen in dotted-quad-Notation enthalten. Ca. 120 MB, 946534
Zeilen, davon 2577 matchende. YMMV.

--
_ | Peter J. Holzer | I know I'd be respectful of a pirate
|_|_) | Sysadmin WSR | with an emu on his shoulder.
| | | hjp@hjp.at |
__/ | http://www.hjp.at/ | -- Sam in "Freefall"

Re: Zeilen mit IP finden die auf IP-Range passen

am 19.05.2007 17:13:26 von Peter Velan

am 19.05.2007 13:51 schrieb Frank Seitz:
> Peter Velan wrote:
>
>> a) einlesen einer Log-Zeile
>> b) prüfen ob " \[(.*?)\] " in Zeile vorkommt
>> c) wenn ja, IP-Quad "(.*?)" in Zahl wandeln
>> d) prüfen ob Zahl innerhalb des gewünschten Bereiches
>> e) Zeile listen wenn innerhalb
>>
>> Da b) und c) für Millionen von Zeilen notwendig ist, kann ich mir nicht
>> vorstellen, dass das Verfahren einigermaßen flott funktionieren würde.
>> Aber ich kann mich da natürlich täuschen.
>
> Da täuscht Du Dich bestimmt. Der (gefühlte) Aufand Deiner
> Pattern-Matches ist bei mir höher.

Ja, da hast du Recht: So ein Musterchen für etwas Komplexeres
hinzubasteln braucht nervtötende Pfriemelei!

Also bin ich jetzt der Sache auf den Grund gegangen und habe beide
Lösungen vermessen:

# time pcregrep -- '\[82.208.180\.' /var/log/meinelogs*
real 0m1.402s
user 0m1.268s
sys 0m0.136s

Meine (nach dem vorgeschlagenen Rezept) umgesetzte "nur-Perl"-Lösung:

# time ./sip.pl 82.208.180.0 - 82.208.180.255
real 0m7.872s
user 0m7.664s
sys 0m0.208s

>> [...] Ich suchte
>> nach einer Möglichkeit die manuelle (und manchmal ziemlich aufwendige)
>> Suchmustererstellung zu automatisieren.
>
> Dann sollte der geniale Vorschlag, die IP-Adressen in Zahlen
> umzurechnen und die zu vergleichen, Dich doch eigentlich überzeugen.

Ja ich wurde überzeugt - auf der ganzen Linie! Trotz der auf den ersten
Blick erheblich längeren Laufzeit [1], kann ich die Perl-Variante nun
schön komfortabel ausgestalten.

Perl rulez! (oder so ähnlich)

Vielen Dank an alle,
Peter

~~~
[1] Höchstwahrscheinlich ist der Rohentwurf des Perlskripts bzgl. der
Performance noch heftig verbesserungsfähig. Für meine Zwecke ist aber
schon dieser erste Schuß eine famose Verbesserung!

Re: Zeilen mit IP finden die auf IP-Range passen

am 19.05.2007 17:50:17 von Peter Velan

am 19.05.2007 17:11 schrieb Peter J. Holzer:
> On 2007-05-19 11:51, Frank Seitz wrote:
>> Peter Velan wrote:
>>> b) prüfen ob " \[(.*?)\] " in Zeile vorkommt
>>> c) wenn ja, IP-Quad "(.*?)" in Zahl wandeln
>>>
>>> Da b) und c) für Millionen von Zeilen notwendig ist, kann ich mir nicht
>>> vorstellen, dass das Verfahren einigermaßen flott funktionieren würde.
>
> b) ist auch bei der Regex-Methode für Millionen von Zeilen notwendig.
> D.h. die Frage ist, was ist schneller:
>
> 1) Eine komplexe Regex matchen
>
> 2) Eine einfache Regex matchen und anschließend eine Zahl (einen String)
> daraus berechnen und vergleichen.
>
> Das hängt davon ab, wie komplex die Regex ist.

Naja die von mir im OP angegebene Regex war für meine konkrete Arbeit
schon ein ziemlicher Extremfall. Sagen wir so, die Muster die ich
"normalerweise" Suche sind eher á la " \[123\.128\.60\." (und hier hört
mein Muster bewußt auf). Warum noch weitertippen, wenn schon die ersten
3 Byte der IP reichen um das gesuchte zu finden?

>>> Aber ich kann mich da natürlich täuschen.
>>
>> Da täuscht Du Dich bestimmt. Der (gefühlte) Aufand Deiner
>> Pattern-Matches ist bei mir höher.
>
> Das Gefühl kann täuschen. Regexes sind hier[0] tatsächlich deutlich
> schneller (3.5 mal schneller als die von mir vorgeschlagene
> inet_aton-Methode, fast 5 mal schneller als die Umwandlung in Zahlen),
> bei Verwendung von reinem Perl. pcregrep ist noch einmal um 50%
> schneller als perl 5.8.8.

Siehe auch mein paralleles Posting mit Zeitmessungen.

>> Dann sollte der geniale Vorschlag, die IP-Adressen in Zahlen
>> umzurechnen und die zu vergleichen, Dich doch eigentlich überzeugen.
>
> Yep. Ob die Suche pro GB jetzt 8 oder 30 Sekunden dauert, ist
> einigermaßen egal, im Vergleich zu den 10 Minuten, die man damit
> verbringt, den Fehler in der Regex zu suchen

Volle Zustimmung!

> (die Regex des OP enthielt
> zwei Fehler: Der erste war ziemlich offensichtlich, der zweite besser
> versteckt und ist mir nur deshalb aufgefallen, weil die Regex nur 2479
> Ergebnisse geliefert hat statt 2577).

Und ich habe mir bei dem Monster so eine Mühe gegeben, diese aber nicht
getestet :-(

Nun habe ich ja, dank eurer Mithilfe, die, unterm Strich "schnellere"
und auf jeden Fall komfortablere Lösung gefunden.

Gruß,
Peter

Re: Zeilen mit IP finden die auf IP-Range passen

am 19.05.2007 18:28:32 von Moritz Lenz

This is an OpenPGP/MIME signed message (RFC 2440 and 3156)
--------------enigD6DD63A5041A1E85253DA388
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

Hallo,

Peter Velan wrote:
> Naja die von mir im OP angegebene Regex war für meine konkrete Arb=
eit
> schon ein ziemlicher Extremfall. Sagen wir so, die Muster die ich
> "normalerweise" Suche sind eher á la " \[123\.128\.60\." (und hier=
hört
> mein Muster bewußt auf).

In diesem Fall suchst du nur nach einem Substring, das geht mit der
Funktion index() üblicherweise nochmal schneller als mit regexes.

Grüße,
Moritz

--=20
Moritz Lenz
http://perl-6.de/ http://moritz.faui2k3.org/


--------------enigD6DD63A5041A1E85253DA388
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: OpenPGP digital signature
Content-Disposition: attachment; filename="signature.asc"

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iD8DBQFGTyW0AAkekJBI0yIRArgKAJ9Q8MaZZj/XMhvzRwl9/4/d0dteAACg q5P4
lw/dC5qnDBCeO/j+hijJjZs=
=+RqQ
-----END PGP SIGNATURE-----

--------------enigD6DD63A5041A1E85253DA388--

Re: Zeilen mit IP finden die auf IP-Range passen

am 20.05.2007 15:39:17 von Peter Velan

am 19.05.2007 18:28 schrieb Moritz Lenz:
> Peter Velan wrote:
>> Naja die von mir im OP angegebene Regex war für meine konkrete Arbeit
>> schon ein ziemlicher Extremfall. Sagen wir so, die Muster die ich
>> "normalerweise" Suche sind eher á la " \[123\.128\.60\." (und hier hört
>> mein Muster bewußt auf).
>
> In diesem Fall suchst du nur nach einem Substring, das geht mit der
> Funktion index() üblicherweise nochmal schneller als mit regexes.

Jein, jetzt habe ich es wohl doch etwas oversimplified! Reguläre Muster
mit gruppierten "|"- Alternativen kamen schon recht oft vor. Beispiel:

IPs im Bereich 12.5.10.128/26 finden:

# muster=' \[12\.5\.10\.1(2[89]|[3-85]\d|9[01])\] ';
# cat meinelogs* | pcregrep -- "$muster";

Für so ein "muster" verrenkt man sich die Finger (und manchmal auch das
Hirn) schon ein wenig ;-)

Die Vereinfachungen die ich mir bisher geleistet habe - z.B. hätte ich
"12.4.0.0/15" mit " [12\.[45]\." gesucht - kann ich mir bei der neuen
Methode ja auch noch einbauen! :-)

Gruß,
Peter