IP-Adressen sortieren

IP-Adressen sortieren

am 06.12.2005 23:45:14 von Erik Griffin

Hallo!

In ger.ct () diskutieren
wir gerade darüber wie man am elegantesten IP-Adressen sortiert.
Es gibt doch bestimmt einen ganz tollen, kurzen und schnellen Weg
mit Perl IP-Adressen zu sortieren oder? Sortiert werden soll wie
folgt:

aaa.bbb.ccc.ddd

Zuerst soll die aaa Spalte, dann die bbb Spalte, dann die ccc Spalte
und dann die ddd Spalte sortiert werden (begonnen wird mit der kleinen
Zahl). Die IP's kommen in Form einer Textdatei pro Zeile eine IP. Sieht
z.B. so aus:

217.91.37.7
87.78.52.97
87.78.55.70
201.9.24.235
213.5.31.195
84.44.214.75
87.78.46.132
195.14.205.35
195.14.207.70
201.19.143.97
213.196.195.9
213.196.252.3
213.28.164.61
81.173.163.16
81.173.172.69
195.14.218.198
195.14.223.213
201.42.181.117
213.140.241.33
213.168.108.73
213.168.111.14

Und draus werden soll sowas:

81.173.163.16
81.173.172.69
84.44.214.75
87.78.46.132
87.78.52.97
87.78.55.70
195.14.205.35
195.14.207.70
195.14.218.198
195.14.223.213
201.9.24.235
201.19.143.97
201.42.181.117
213.5.31.195
213.28.164.61
213.140.241.33
213.168.108.73
213.168.111.14
213.196.195.9
213.196.252.3
217.91.37.7

Der bisher kürzeste Weg der mir einfiel wäre der folgende:

cat ipliste | sed 's/\./ /g' | gawk '{printf("%03d %03d %03d %03d\n", $1,$2,$3,$4)};' | sort -n -t " " | gawk '{printf("%d.%d.%d.%d\n",$1,$2,$3,$4);}'


Verbesserungsvorschläge?



mfg
Erik

Re: IP-Adressen sortieren

am 07.12.2005 00:29:04 von Christian Lackas

* Erik Griffin [2005-12-06]:

Hallo Erik,

> In ger.ct () diskutieren
> wir gerade darüber wie man am elegantesten IP-Adressen sortiert.
> Es gibt doch bestimmt einen ganz tollen, kurzen und schnellen Weg
> mit Perl IP-Adressen zu sortieren oder? Sortiert werden soll wie
> folgt:

ich würde das in einer Zeile (ok zwei mit Shebang) etwa so machen:

#! /usr/local/bin/perl -wl
$,='.';$_=pack+C4,split'\.'for@_=<>;print+unpack+C4,$_,for+sort@_;


$ ./sortip.pl < iplist

> Der bisher kürzeste Weg der mir einfiel wäre der folgende:
>
> cat ipliste | sed 's/\./ /g' | gawk '{printf("%03d %03d %03d %03d\n",
> $1,$2,$3,$4)};' | sort -n -t " " | gawk
> '{printf("%d.%d.%d.%d\n",$1,$2,$3,$4);}'

Die Lösung erst alles in 4 Byte zu verpacken (das ist ja die kanonische
Form von IP-Adressen) und dann zu sortieren dürfte auch noch deutlich
performanter sein, als dein Konstrukt hier (von den ganzen
unterschiedlichen Prozessen mal abgesehen).

Gruß
Christian

--
Ein Experte ist ein Mann, der hinterher genau sagen kann, warum seine
Prognose nicht gestimmt hat.
(Winston Churchill, engl. Staatsmann, 1874-1965)
http://www.lackas.net/ Perl Delphi Linux MP3 Searchengines Domainchecker

Re: IP-Adressen sortieren

am 07.12.2005 00:42:18 von Christian Lackas

* Christian Lackas [2005-12-06]:

Hallo Golfer,

> ich würde das in einer Zeile (ok zwei mit Shebang) etwa so machen:
> #! /usr/local/bin/perl -wl
> $,='.';$_=pack+C4,split'\.'for@_=<>;print+unpack+C4,$_,for+sort@_;

möchte hier noch einen Vorschlag machen:

$,='.';print+unpack+C4,$_,for+sort+map{pack+C4,split'\.'}<>

Das ist nochmal 6 Zeichen kürzer.

Gruß
Christian


--
Unter Diskussionen verstehen Männer die Kunst, den Partner zum Schweigen
zu bringen. Frauen verstehen darunter die Kunst, den Partner nicht zum
Reden kommen zu lassen.
(Fritz Eckhard, österr. Schauspieler und Autor)

Re: IP-Adressen sortieren

am 07.12.2005 01:16:39 von Slaven Rezic

Erik Griffin <1f4e5381573d4a9c00e0b61302a4167f@nurfuerspam.de> writes:

> Hallo!
>
> In ger.ct () diskutieren
> wir gerade darüber wie man am elegantesten IP-Adressen sortiert.
> Es gibt doch bestimmt einen ganz tollen, kurzen und schnellen Weg
> mit Perl IP-Adressen zu sortieren oder? Sortiert werden soll wie
> folgt:
>
> aaa.bbb.ccc.ddd
>
> Zuerst soll die aaa Spalte, dann die bbb Spalte, dann die ccc Spalte
> und dann die ddd Spalte sortiert werden (begonnen wird mit der kleinen
> Zahl). Die IP's kommen in Form einer Textdatei pro Zeile eine IP. Sieht
> z.B. so aus:
>
[...]
>
> Der bisher kürzeste Weg der mir einfiel wäre der folgende:
>
> cat ipliste | sed 's/\./ /g' | gawk '{printf("%03d %03d %03d %03d\n", $1,$2,$3,$4)};' | sort -n -t " " | gawk '{printf("%d.%d.%d.%d\n",$1,$2,$3,$4);}'
>
>
> Verbesserungsvorschläge?
>

Es sieht so aus, als ob man IP-Nummern bei der Sortierung wie
Versionsnummern behandeln kann:

cat /tmp/ipliste | perl -MSort::Versions -e 'print sort versioncmp <>'

Gruß,
Slaven

--
Slaven Rezic - slaven rezic de

Lost in your Tk widget tree? Try
http://user.cs.tu-berlin.de/~eserte/src/perl/Tk-WidgetDump/

Re: IP-Adressen sortieren

am 07.12.2005 01:32:06 von Achim Grolms

Slaven Rezic wrote:

> cat /tmp/ipliste | perl -MSort::Versions -e 'print sort versioncmp <>'

perl -MSort::Versions -e 'print sort versioncmp <>' < /tmp/ipliste

Re: IP-Adressen sortieren

am 07.12.2005 01:42:59 von Christian Lackas

* Slaven Rezic [2005-12-07]:

Hallo Slaven,

> cat /tmp/ipliste | perl -MSort::Versions -e 'print sort versioncmp <>'

Useless use of cat[1]

Besser:

perl -MSort::Versions -e 'print sort versioncmp <>' < /tmp/ipliste

Da <> aber ja auch Dateinamen schluckt statt von STDIN zu lesen geht
sogar

perl -MSort::Versions -e 'print sort versioncmp <>' /tmp/ipliste

und das sogar mit mehreren Dateien, es gibt hier also keinerlei Grund
cat einzusetzen.

Gruß
Christian

[1] http://www.ruhr.de/home/smallo/award.html#cat

--
Murphys Law 24:
Wenn die Tatsachen mit der Theorie nicht übereinstimmen, muß man eben
die Tatsachen ändern.
http://www.lackas.net/ Perl Delphi Linux MP3 Searchengines Domainchecker

Re: IP-Adressen sortieren

am 07.12.2005 10:54:30 von Slaven Rezic

Christian Lackas writes:

> * Slaven Rezic [2005-12-07]:
>
> Hallo Slaven,
>
> > cat /tmp/ipliste | perl -MSort::Versions -e 'print sort versioncmp <>'
>
> Useless use of cat[1]
>
[...]
>
> [1] http://www.ruhr.de/home/smallo/award.html#cat
>

Ich verwende "cat" gerne. Beispiel: max experimentiert mit einer Pipe,
die so aussieht:

grep ... | ...

Während der Experimentierphase will man vielleicht auch die
ungefilterte Ausgabe sehen. Natürlich ersetze ich das "grep" einfach
durch "cat". Eine Umlenkung daraus zu basteln bedeutet: mehr Zeichen
ändern und genau aufpassen, dass man den Umlenkungspfeil richtig rum
setzt. Wenn ich ihn nämlich vor das Kommando setze, muss ich immer
lange überlegen, dass ich es nicht falsch mache.

Ich sehe das mit dem "useless cat" viel gelassener --- immerhin
programmiere ich in Perl und nicht in Assembler.

Gruß,
Slaven

--
Slaven Rezic - slaven rezic de

Visualize Makefiles with GraphViz:
http://user.cs.tu-berlin.de/~eserte/src/perl/GraphViz-Makefi le/

Re: IP-Adressen sortieren

am 07.12.2005 12:31:36 von Christian Lackas

* Slaven Rezic [2005-12-07]:

Hallo Slaven,

> > > cat /tmp/ipliste | perl -MSort::Versions -e 'print sort versioncmp <>'
> > Useless use of cat[1]
> > [1] http://www.ruhr.de/home/smallo/award.html#cat
> Ich verwende "cat" gerne.

das sei dir auch unbenommen. Aber wenn es in der Aufgabenstellung gerade
um Kompaktheit und Eleganz geht, dann darf auch ein Hinweis auf die
unnötige Verwendung von cat erlaubt sein.
Findest du in diesem speziellen Fall die Verwendung von cat sinnvoll,
würdest du sie also auch andere in diesem Fall weiterempfehlen?

> Beispiel: man experimentiert mit einer Pipe,
> die so aussieht:
> grep ... | ...
> Während der Experimentierphase will man vielleicht auch die
> ungefilterte Ausgabe sehen. Natürlich ersetze ich das "grep" einfach
> durch "cat".

Lass mich auch mal ein willkürliches (etwas konkreteres) Beispiel
konstruieren:

Die Datei 'foo' enthalt eine Liste mit den Pfaden zu Dateien (der
Einfachheit halber ohne Sonderzeichen). Und ich möchte jetzt alle
..bak-Dateien darin löschen.

grep .bak\$ foo | xargs rm -f

Hier jetzt einfach mal zum Testen cat zu verwenden, wäre nicht unbedingt
eine gute Idee.

Außerdem verwendest du in deinem Beispiel nirgendwo Perl, was ja die
gesamte Funktionalität von cat schon von Hause aus mitbringt, so dass
hier noch nichtmal Umleitungen nötig sind.

> Eine Umlenkung daraus zu basteln bedeutet: mehr Zeichen ändern und

Du musst in beiden Fällen das grep und das Pattern löschen. In deinem
Fall ein 'cat' einfügen, im anderen ein '<' einfügen und das '|'
löschen.
Der Befehl cat macht hier nur wirklich Sinn, wenn es um mehrere Dateien
geht (und genau dafür ist er ja gemacht).

> genau aufpassen, dass man den Umlenkungspfeil richtig rum setzt.
> Wenn ich ihn nämlich vor das Kommando setze, muss ich immer
> lange überlegen, dass ich es nicht falsch mache.

Meinst du jetzt für die Richtung der Aus-/Eingabe? Die ist doch vorne
genauso wie hinten. Oder weil du nicht unabsichtlich etwas überschrieben
willst? Dann hilft dir ja idR deine Shell weiter, z.B. bei der Bourne
Shell

set -o noclobber

> Ich sehe das mit dem "useless cat" viel gelassener --- immerhin
> programmiere ich in Perl und nicht in Assembler.

In dem Fall ist es eher Shell-Progammierung, und verglichen zu Perl ist
die Analogie zu Assembler nicht wirklich weit weg. :-)

Es geht mir auch nicht darum dir die Verwendung von cat zu verleiden,
aber Optimierungspotential habe ich in deiner Lösung sehr wohl gesehen.

Gruß
Christian

--
Als ich den Leuten in Nordirland erzählte, dass ich Atheist sei, stand
eine Frau im Publikum auf und fragte: "Nun gut, aber ist es der
katholische oder der protestantische Gott, an den Sie nicht glauben?"
(Quentin Crisp)

Re: IP-Adressen sortieren

am 07.12.2005 21:15:15 von Slaven Rezic

Christian Lackas writes:

> * Slaven Rezic [2005-12-07]:
>
> Hallo Slaven,
>
> > > > cat /tmp/ipliste | perl -MSort::Versions -e 'print sort versioncmp <>'
> > > Useless use of cat[1]
> > > [1] http://www.ruhr.de/home/smallo/award.html#cat
> > Ich verwende "cat" gerne.
>
> das sei dir auch unbenommen. Aber wenn es in der Aufgabenstellung gerade
> um Kompaktheit und Eleganz geht, dann darf auch ein Hinweis auf die
> unnötige Verwendung von cat erlaubt sein.
> Findest du in diesem speziellen Fall die Verwendung von cat sinnvoll,
> würdest du sie also auch andere in diesem Fall weiterempfehlen?

In diesem Fall habe ich "cat file" als Platzhalter für "es kommt
irgendeine Eingabe herein, womöglich aus einem anderen Programm"
angesehen. Wenn ich ehrlich bin, habe ich das "cat" nur vom OP kopiert
:-)

>
> > Beispiel: man experimentiert mit einer Pipe,
> > die so aussieht:
> > grep ... | ...
> > Während der Experimentierphase will man vielleicht auch die
> > ungefilterte Ausgabe sehen. Natürlich ersetze ich das "grep" einfach
> > durch "cat".
>
> Lass mich auch mal ein willkürliches (etwas konkreteres) Beispiel
> konstruieren:
>
> Die Datei 'foo' enthalt eine Liste mit den Pfaden zu Dateien (der
> Einfachheit halber ohne Sonderzeichen). Und ich möchte jetzt alle
> .bak-Dateien darin löschen.
>
> grep .bak\$ foo | xargs rm -f
>
> Hier jetzt einfach mal zum Testen cat zu verwenden, wäre nicht unbedingt
> eine gute Idee.

Nope, bei xargs ist es immer ein eingeschobenes "echo".

>
> Außerdem verwendest du in deinem Beispiel nirgendwo Perl, was ja die
> gesamte Funktionalität von cat schon von Hause aus mitbringt, so dass
> hier noch nichtmal Umleitungen nötig sind.
>
> > Eine Umlenkung daraus zu basteln bedeutet: mehr Zeichen ändern und
>
> Du musst in beiden Fällen das grep und das Pattern löschen. In deinem
> Fall ein 'cat' einfügen, im anderen ein '<' einfügen und das '|'
> löschen.
> Der Befehl cat macht hier nur wirklich Sinn, wenn es um mehrere Dateien
> geht (und genau dafür ist er ja gemacht).
>
> > genau aufpassen, dass man den Umlenkungspfeil richtig rum setzt.
> > Wenn ich ihn nämlich vor das Kommando setze, muss ich immer
> > lange überlegen, dass ich es nicht falsch mache.
>
> Meinst du jetzt für die Richtung der Aus-/Eingabe? Die ist doch vorne
> genauso wie hinten.

Das ist das Problem :-) Wenn es hinten steht, dann ist der
Umlenkungspfeil gleichzeitig ein Separator zwischen Programm und
umgelenkter Datei und man sieht schnell, in welche Richtung die Daten
fließen. Wenn es vorne steht, dann gibt es keinen Separator (nur
Whitespace) und (ich jedenfalls) sehe die Richtung des Datenflusses
nicht auf Anhieb.

> Oder weil du nicht unabsichtlich etwas überschrieben
> willst? Dann hilft dir ja idR deine Shell weiter, z.B. bei der Bourne
> Shell
>
> set -o noclobber
>

Da scheint bei meiner zsh-Konfiguration (benutze ich auf Arbeit)
gesetzt zu sein. Zuhause benutze ich tcsh, da müsste ich erst einmal
nachgucken. Aber oft genug arbeitet man mit "unbekannten" oder
"schwach konfigurierten" Shells (zum Beispiel root-Shells), da kann
man sich nicht darauf verlassen.

Gruß,
Slaven

--
Slaven Rezic - slaven rezic de

need xpm or ppm output from GD?
http://search.cpan.org/search?mode=module&query=GD::Convert

Re: IP-Adressen sortieren

am 08.12.2005 09:10:36 von Frank Seitz

Daniel Fischer wrote:
> Christian Lackas!
>
>> perl -MSort::Versions -e 'print sort versioncmp <>' /tmp/ipliste
>
> Useless use of print :P
>
> Besser:
>
> perl -MSort::Versions -pe 'sort versioncmp' /tmp/ipliste

Das sieht mir nicht so aus, als ob es dasselbe tut.

Grüße
Frank
--
Dipl.-Inform. Frank Seitz; http://www.fseitz.de/
Tel: 04103/180301; Fax: -02; Industriestr. 31, 22880 Wedel

Re: IP-Adressen sortieren

am 08.12.2005 09:46:15 von Daniel Fischer

Christian Lackas!

> perl -MSort::Versions -e 'print sort versioncmp <>' /tmp/ipliste

Useless use of print :P

Besser:

perl -MSort::Versions -pe 'sort versioncmp' /tmp/ipliste


Gruß
Daniel

Re: IP-Adressen sortieren

am 08.12.2005 10:24:10 von Daniel Fischer

Frank Seitz!


> Das sieht mir nicht so aus, als ob es dasselbe tut.

Da hast Du recht. Ich ziehe meinen Einwand zurück.


Gruß
Daniel

Re: IP-Adressen sortieren

am 08.12.2005 11:26:43 von Christian Lackas

* Daniel Fischer [2005-12-08]:

Hallo Daniel,

> Christian Lackas!

ja, hier.

> > perl -MSort::Versions -e 'print sort versioncmp <>' /tmp/ipliste
> Useless use of print :P
> Besser:
> perl -MSort::Versions -pe 'sort versioncmp' /tmp/ipliste

was dann zwar äquivalent zu

cat /tmp/ipliste

ist, aber nichts mit einer Sortierung zu tun hat.

Gruß
Christian

--
Planung ist die Ersetzung des Zufalls durch den Irrtum.
http://www.lackas.net/ Perl Delphi Linux MP3 Searchengines Domainchecker