7 Stimmen

Sortieren von IP-Adressen in vim

Ich habe gerade den Befehl :sort n in vim (wie konnte ich das nicht wissen?!), das über fast genau das getan, was ich brauche.

Was ich jedoch zu sortieren versuche, ist eine lange Liste von IP-Adressen (es handelt sich um eine "allow hosts"-Datei, die Include d in unserer Apache-Konfiguration), und es wäre schön, wenn :sort n erkennen zu können, dass 123.45.6.7 sollte vor 123.45.16.7 (zum Beispiel).

Ist es eine sichere Annahme, dass ich weniger zwanghaft sein sollte und mir keine Sorgen machen sollte, weil ich nicht in der Lage sein werde, dies ohne ein leicht komplexes sed o awk Befehl oder so etwas?

Um es klar zu machen, die Zeilen sehen alle ungefähr so aus:

Allow from 1.2.3.4
Allow from 5.6.7.8
Allow from 9.10.11.12

usw.

17voto

Benoit Punkte 72929

Vim sort scheint in der Praxis stabil zu sein (aber es ist nicht garantiert). Daher können Sie es versuchen:

:%sort n /.*\./
:%sort n /\.\d\+\./
:%sort n /\./
:%sort n

Das sortiert nach der Nummer nach dem letzten Punkt ( * ist gierig), dann nach der Zahl nach dem ersten Punkt, die auf einen Punkt und Ziffern folgt, dann nach der Zahl nach dem ersten Punkt und zuletzt nach der ersten Zahl.

3voto

ib. Punkte 26240

Eine einfache Möglichkeit, die richtige Sortierreihenfolge zu erreichen, ohne ohne sich auf die Stabilität des Sortieralgorithmus zu verlassen, der von der :sort Befehls ist es, den Zahlen in der IP-Datei Nullen voranzustellen Adressen voranzustellen, so dass alle Bestandteile der Adressen aus genau drei Ziffern bestehen.

  1. Stellen Sie den einstelligen und zweistelligen Zahlen Nullen voran:

    :%s/\<\d\d\?\>/0&/g|%&&
  2. Sortieren Sie die Zeilen, die IP-Adressen als Text vergleichen:

    :sort r/\(\d\{3}\)\%(\.\d\{3}\)\{3}/
  3. Überflüssige führende Nullen werden entfernt:

    :%s/\<00\?\ze\d//g

Um alle drei Schritte in einem einzigen Befehl auszuführen, kann man Folgendes verwenden Einzeiler verwenden:

:%s/\<\d\d\?\>/0&/g|%&&|sor r/\(\d\{3}\)\%(\.\d\{3}\)\{3}/|%s/\<00\?\ze\d//g

0voto

FatalError Punkte 51437

Ich bin kein Vim-Benutzer, daher kann ich keine direkte Möglichkeit anbieten, dies mit eingebauten Befehlen zu tun, aber es ist möglich, einen Textabschnitt durch die Ausgabe zu ersetzen, die durch einen Befehl ausgeführt wird. So könnte ein einfaches Skript wie dieses verwendet werden:

#!/usr/bin/python

import sys

input_lines = sys.stdin.readlines()
sorted_lines = sorted(input_lines,
                      key=lambda line: map(int, line.split()[-1].split('.')))
for line in sorted_lines:
    sys.stdout.write(line)

Siehe https://www.linux.com/learn/tutorials/442419-vim-tips-working-with-external-commands Abschnitt "Filtern von Text durch externe Filter", in dem erklärt wird, wie Sie dies als Filter in vim verwenden können.

Dieses Skript sollte das tun, was Sie wollen, und wird in jeder Region funktionieren, in der alle ausgewählten Zeilen auf eine IPv4-Adresse enden.

0voto

MOHRE Punkte 1020

Sie können verwenden:

:%!sort -t . -k 1,1n -k 2,2n -k 3,3n -k 4,4n

-t . bedeutet Verwendung . als Begrenzungszeichen. Sortieren Sie dann numerisch von Spalte 4 nach Spalte 1.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X