Anzeige:
Ergebnis 1 bis 13 von 13

Thema: Wie IPs aus einer Text-Datei extrahieren?

  1. #1
    Registrierter Benutzer
    Registriert seit
    03.09.2006
    Beiträge
    120

    Question Wie IPs aus einer Text-Datei extrahieren?

    Ich benötige IPV4-Adressen aus Text-Dateien extrehieret.
    Wie bekommt man das möglichst einfach hin, aus einem Bash-Skript?

    Dazu brauche ich auch einen Vergleich von IPV4-Adressen, wobei unterschieden werden
    soll zwischen Gleichheit, Ähnlichkeit (nur das letzte Byte ist unterschiedlich) und sonst (d. h.
    Verschiedenheit).
    Wie bekommt man das hin?

  2. #2
    Registrierter Benutzer
    Registriert seit
    07.05.2007
    Beiträge
    656
    Moin,

    zum Extrahieren nimmst Du z. B. grep (die Option -o gibt nur die Matches aus), dann sortierst Du; das Vergleichen ist etwas diffus beschrieben. Wie soll denn die Ausgabe aussehen? Passend für solche Geschichten ist z. B. der awk, kann aber auch in einer reinen Shell-Schleife gemacht werden.

    Schreib mal, was Du schon hast, dann kann man auch konkreter helfen.

    Jan

    P.S.: Eine regex für IPs sollte berücksichtigen, dass in den Einzelziffern nur 0..255 auftreten kann. Das lässt sich am besten über mehrere regex abbilden, die man dann in eine Datei schreibt und dem grep vorwirft (Option -f).

  3. #3
    Registrierter Benutzer
    Registriert seit
    03.09.2006
    Beiträge
    120
    Hm, ich nehme am Besten wohl ein

    | awk '{ print $5}'

    weil das für die Ausgabe von dig reicht.
    Ich habe auch den Ausdruck

    \b(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b

    gefunden, aber awk erscheint mir sinnvoller.

  4. #4
    Registrierter Benutzer
    Registriert seit
    07.05.2007
    Beiträge
    656
    Moin,

    Zitat Zitat von Linus Beitrag anzeigen
    Hm, ich nehme am Besten wohl ein

    | awk '{ print $5}'

    weil das für die Ausgabe von dig reicht.
    Warum beschreibst Du Dein Problem nicht gleich genauer? Hätte ich gewusst, dass Du die dig-Ausgabe filtern willst, dann hätte ich Dir auch einen anderen Weg vorgeschlagen.

    Wenn Du den o. g. awk auf einen dig ohne Optionen anwendest, dann reicht die Ausgabe von $5 aber nicht - Du musst dann schon vorher noch die Zeile nach ";; ANSWER SECTION:" ausfiltern.

    Mein Tipp für diesen speziellen Fall lautet: Du brauchst gar kein Feld zu extrahieren:
    Code:
    dig +short host.domain.tld
    192.168.1.2
    Jan

  5. #5
    Registrierter Benutzer
    Registriert seit
    03.09.2006
    Beiträge
    120
    Ja, stimmt, aber nur im Prinzip: Zu einigen Domains kommt statt einer IP die Fehlermeldung

    ;; connection timed out; no servers could be reached

    und zu anderen erhalte ich statt einer IP andere Domains wie youtube.l.google.com, wohl weil die als CNAME ausgegeben werden.

  6. #6
    Registrierter Benutzer
    Registriert seit
    07.05.2007
    Beiträge
    656
    Moin,

    dann würde ich aber die dig-Ausgabe am besten innerhalb eines einzigen awk auswerten und nicht in einer Textdatei zwischenparken.

    Jan

  7. #7
    Registrierter Benutzer
    Registriert seit
    03.09.2006
    Beiträge
    120
    Zitat Zitat von jan61 Beitrag anzeigen
    Moin,

    dann würde ich aber die dig-Ausgabe am besten innerhalb eines einzigen awk auswerten und nicht in einer Textdatei zwischenparken.

    Jan
    Das reicht nicht: Die IPs kann ich direkt vergleichen, aber wenn der Vergleich fehlschlägt, z. B. wgen Round Robin IPs, dann will ich die canonical names vergleichen.
    Außerdem werden zu Domains wie google mehrere IPs ausgegeben; die müssen erstmal mittels sort sortiert werden.

  8. #8
    Registrierter Benutzer
    Registriert seit
    07.05.2007
    Beiträge
    656
    Moin,

    Zitat Zitat von Linus Beitrag anzeigen
    Das reicht nicht: Die IPs kann ich direkt vergleichen, aber wenn der Vergleich fehlschlägt, z. B. wgen Round Robin IPs, dann will ich die canonical names vergleichen.
    Außerdem werden zu Domains wie google mehrere IPs ausgegeben; die müssen erstmal mittels sort sortiert werden.
    ja und? Hast Du mal im awk-Manual gestöbert, was der alles kann? Du kannst Dir assoziative Arrays aufbauen (Hashes), hast Sortierfunktionen, hast einen END-Block, in dem Du nach dem Einlesen der Daten die erzeugten assoziativen Arrays bearbeiten kannst, hast diverse Möglichkeiten zum Erkennen und Manipulieren von Strings mittels regulärer Ausdrücke ...

    Du wirfst uns immer wieder nur Informationsbröckchen hin von dem, was Du eigentlich machen willst. So macht das Helfen keinen Spaß! Und eine saubere + effiziente Lösung wird für Dich dabei auch nicht rausspringen.

    Wenn Du schreiben würdest: "Ich will eine Liste von Servernamen in IP-Adressen auflösen und vergleichen und benutze dazu dig, die Ausgabe sieht so aus, folgende Spezialfälle will ich bearbeiten können (Beispielausgaben des dig), ich habe mir das wie folgt vorgestellt (geplanter Ablauf, bisher vorhandener Code), komme aber da und da nicht weiter", dann könnten wir uns gleich vorstellen, was Du willst. Sowas macht natürlich mehr Arbeit bei der Problembeschreibung, aber wir machen uns ja auch die Mühe, Lösungen für Dein Problem zu suchen und ggf. auch mal zu testen.

    Jan
    Geändert von jan61 (17-05-2009 um 23:27 Uhr)

  9. #9
    Registrierter Benutzer
    Registriert seit
    03.09.2006
    Beiträge
    120
    Achso, dann kann AWK mehr als ich dachte
    Also hier ist die Liste der Ausgaben von dig +short, die ich gesehen habe:

    Meistens wird eine IP wie
    134.60.1.111.
    ausgegeben.

    Zu großen Domains wie google.com werden mehrere IPs ausgegeben
    (eine je Zeile).

    Manchmal wird nichts (leere Ausgabe) ausgegeben, zu nicht (mehr)
    existenden Domains.

    Manchmal ausgegeben wird ein canonical Name und (mind.) eine IP,
    z. B.
    ftp.pochta.ru.
    82.204.219.221

    Sehr selten ausgegeben wird (bei einem Timeout von 20 s)
    ;; connection timed out; no servers could be reached

    Was mir noch fehlt ist der Vergleich der Canonical Names sowie festzustellen, zu welchen Domains die DNS-Server per default auflösen, denn mir ist aufgefallen, das einige DNS-Server zu einigen Domains nichts ausgeben während andere zu google führende IPs ausgeben.
    Der Vergleich der Canonical Names müsste mit dem AWK gehen, aber wie?

    Der Vergleich mit AWK ist aber nicht wichtig, denn das bekomme ich auch mit egrep und diff hin
    Geändert von Linus (18-05-2009 um 01:10 Uhr)

  10. #10
    Registrierter Benutzer
    Registriert seit
    07.05.2007
    Beiträge
    656
    Moin,

    Zitat Zitat von Linus Beitrag anzeigen
    Achso, dann kann AWK mehr als ich dachte
    Sicher kann er das, das ist eigentlich eine komplette Programmiersprache mit Mustererkennung, C-ähnlicher Sprachsyntax und einem erklecklichen Funktionsvorrat.

    Zitat Zitat von Linus Beitrag anzeigen
    Also hier ist die Liste der Ausgaben von dig +short, die ich gesehen habe:
    Für die Behandlung in awk würde ich andere dig-Optionen empfehlen, die Dir bessere Kontrolle, z. B. beim Füttern mit mehreren Hostnamen gleichzeitig bringen. Die nachfolgenden Optionen blenden alles aus, was ich nicht sehen will:

    Code:
    jan@jack:~> dig +nocmd +nocomments +noauthority +noadditional +nostats www.google.de www.g.de www.heise.de
    ;www.google.de.                 IN      A
    www.google.de.          25456   IN      CNAME   www.google.com.
    www.google.com.         27069   IN      CNAME   www.l.google.com.
    www.l.google.com.       270     IN      A       209.85.135.103
    www.l.google.com.       270     IN      A       209.85.135.104
    www.l.google.com.       270     IN      A       209.85.135.147
    www.l.google.com.       270     IN      A       209.85.135.99
    ;www.g.de.                      IN      A
    ;www.heise.de.                  IN      A
    www.heise.de.           72815   IN      A       193.99.144.85
    Da haben wir gleich mal ein paar der Varianten der möglichen Antworten. Die mit Semikolon beginnenden Zeilen dienen Dir als Marker, dass jetzt ein neuer Host dran ist.

    Die "connection timed out"-Meldung dürfte doch eigentlich nur kommen, wenn Du gar keinen DNS-Server im Zugriff hast, oder? Dann sollte mit einer Fehlermeldung abgebrochen werden.

    Ich habe mal "quick&dirty" ein Beispiel gebastelt, wie man im awk sowas bearbeiten kann. Da mir noch nicht klar ist, ob Du nun innerhalb der Host-Ausgaben oder insgesamt vergleichen willst und was dabei rauskommen soll, habe ich mal die 1. Variante genommen. Zuerst das awk-Kommandoscript (die Pattern, die dann bestimte Aktionen auslösen, habe ich markiert):
    Code:
    jan@jack:~/tmp> cat ip.awk 
    BEGIN { hostname = ""; }   
    /^;; connection timed out/ { # Fehler: DNS-Server nicht gefunden
      print "ERROR: DNS-Server antwortet nicht";                    
      exit;                                                         
    }                                                               
    /^;/ { # neuer Host: wenn alter Host != "", dann Auswertungen   
      if (length(hostname) > 0) {                                   
        print "Host: " hostname;                                    
        found = 0;                                                  
        asort(ip_arr);                                              
        for (n in ip_arr) {                                         
          print "\tIP: " ip_arr[n];                                 
          found++;                                                  
        }                                                           
        asort(dom_arr);                                             
        prev_dom = "";                                              
        for (n in dom_arr) {                                        
          if (prev_dom != dom_arr[n]) print "\tDomain: " dom_arr[n];
          prev_dom = dom_arr[n];                                    
          found++;                                                  
        }                                                           
        asort(canon_arr);                                           
        for (n in canon_arr) {                                      
          print "\tCNAME: " canon_arr[n];                           
          found++;                                                  
        }                                                           
        if (found == 0) print "\tHost nicht gefunden";
      }
      # Variablen neu initialisieren
      delete ip_arr;
      delete dom_arr;
      delete canon_arr;
      hostname = gensub(/^;(.+)\.$/, "\\1", "g", $1);
    }
    $4 == "CNAME" { # canonical name; array canon_arr: Key = NR, Wert = CNAME
      canon_arr[NR] = $5;
    }
    $4 == "A" { # ip adresse; array ip_arr: Key = NR, Wert = IP
                # domain; array dom_arr: Key = NR, Wert = Domain
      dom_arr[NR] = gensub(/\.[0-9]+$/, "", "1", $5);
      ip_arr[NR] = $5;
    }
    END { # vom letzten Host die Daten
      print "Host: " hostname;
      found = 0;
      asort(ip_arr);
      for (n in ip_arr) {
        print "\tIP: " ip_arr[n];
        found++;
      }
      asort(dom_arr);
      prev_dom = "";
      for (n in dom_arr) {
        if (prev_dom != dom_arr[n]) print "\tDomain: " dom_arr[n];
        prev_dom = dom_arr[n];
        found++;
      }
      asort(canon_arr);
      for (n in canon_arr) {
        print "\tCNAME: " canon_arr[n];
        found++;
      }
      if (found == 0) print "\tHost nicht gefunden";
    }
    So, und jetzt das Ergebnis:
    Code:
    jan@jack:~/tmp> dig +nocmd +nocomments +noauthority +noadditional +nostats www.google.de www.g.de www.heise.de | awk -f ip.awk
    Host: www.google.de
            IP: 209.85.129.104
            IP: 209.85.129.147
            IP: 209.85.129.99
            Domain: 209.85.129
            CNAME: www.google.com.
            CNAME: www.l.google.com.
    Host: www.g.de
            Host nicht gefunden
    Host: www.heise.de
            IP: 193.99.144.85
            Domain: 193.99.144
    Das ist als Basis zum Weiterprobieren gedacht. Ich habe nur ein paar der Möglichkeiten des awk demonstriert, um ein gründliches Studium der Manual-Page wirst Du nicht herumkommen ;-)

    Jan
    Geändert von jan61 (18-05-2009 um 21:51 Uhr) Grund: Server != Host; Server ist in dig DNS-Server

  11. #11
    Registrierter Benutzer
    Registriert seit
    03.09.2006
    Beiträge
    120
    Danke, aber ich sehe keine Vorteil darin mehr Ausgaben als mit

    dig +short <domain>

    zu produzieren.
    Übrigens habe ich zu einigen Domains auch zwei Canonical Names und mehrere IPs gesehen; auch mit +short ist die Ausgabe von dig nicht einfach.

    Hier ist das Skript, an dem ich arbeite:

    https://sslsites.de/www.true-random...._dns_check1.sh

    und die Liste der rund 10.000 Domains hier:

    https://sslsites.de/www.true-random....nsur/list2.txt

  12. #12
    Registrierter Benutzer
    Registriert seit
    07.05.2007
    Beiträge
    656
    Moin,

    Zitat Zitat von Linus Beitrag anzeigen
    Danke, aber ich sehe keine Vorteil darin mehr Ausgaben als mit

    dig +short <domain>

    zu produzieren.
    Übrigens habe ich zu einigen Domains auch zwei Canonical Names und mehrere IPs gesehen; auch mit +short ist die Ausgabe von dig nicht einfach.
    Der Mehrwert liegt in meinem Beispiel einfach darin, dass Du unterscheiden kannst, welcher Host gerade geprüft wird, mit der einzeiligen Ausgabe von +short siehst Du ja nur IPs / Canonical Names oder eben nichts. Du umgehst das in Deinem Script, indem Du für jeden einzelnen Host einen separaten dig absetzt und das Ergebnis in eine separate Datei schreibst - finde ich ehrlich gesagt nicht besonders schön.

    Wie Du an der awk-Ausgabe in meinem Beispiel sehen konntest, wird der Fall mehrerer CNAMES oder mehrerer IPs durchaus berücksichtigt.

    Ein kurzer Blick auf Dein Script bestätigt meinen Verdacht: Sehr viele externe Programmaufrufe - sehr oft auch zeilenweise (bei 10.000 Hosts kein Pappenstiel), viele temporäre Dateien. Ich bin schon der Meinung, dass man das eleganter und ressourcenschonender mit awk oder z. B. auch Perl hinkriegt, aber nun ja: Es ist Dein Script ;-)

    Eine grundsätzliche Bemerkung: Du benutzt sehr oft die folgende Schleifensyntax:
    Code:
    cat datei | while read line; do
      ...
    done
    Das geht auch ohne Pipe + cat, damit sparst Du schonmal 2 Prozesse je Schleife ein:
    Code:
    while read line; do
      ...
    done <datei
    Jan

  13. #13
    Registrierter Benutzer
    Registriert seit
    03.09.2006
    Beiträge
    120
    Zitat Zitat von jan61 Beitrag anzeigen
    Der Mehrwert liegt in meinem Beispiel einfach darin, dass Du unterscheiden kannst, welcher Host gerade geprüft wird, mit der einzeiligen Ausgabe von +short siehst Du ja nur IPs / Canonical Names oder eben nichts. Du umgehst das in Deinem Script, indem Du für jeden einzelnen Host einen separaten dig absetzt und das Ergebnis in eine separate Datei schreibst - finde ich ehrlich gesagt nicht besonders schön.
    Bei wenigen Domains ist das machbar, aber ich möchte tausende Domains abfragen und dahar weitgehend automatisiert verarbeiten. Ich möchte nur die "Problemfälle" ausgefiltert bekommen, denn mit dem Skript soll ja sichtbar werden, welche "geheimen" Sperrlisten die Provider denn verwenden


    Zitat Zitat von jan61 Beitrag anzeigen
    Ein kurzer Blick auf Dein Script bestätigt meinen Verdacht: Sehr viele externe Programmaufrufe - sehr oft auch zeilenweise (bei 10.000 Hosts kein Pappenstiel), viele temporäre Dateien. Ich bin schon der Meinung, dass man das eleganter und ressourcenschonender mit awk oder z. B. auch Perl hinkriegt, aber nun ja: Es ist Dein Script ;-)
    Das ist kein Problem: Es läuft bei mir in einer RAMDisk auf einem PC mit 8 Cores, 4 Nodes sowie 16 GiB RAM ausreichend schnell.
    Ok, auf dem IPhone oder einem Eepc wäre das Skript wohl langsam


    Zitat Zitat von jan61 Beitrag anzeigen
    Ene grundsätzliche Bemerkung: Du benutzt sehr oft die folgende Schleifensyntax:
    Code:
    cat datei | while read line; do
      ...
    done
    Das geht auch ohne Pipe + cat, damit sparst Du schonmal 2 Prozesse je Schleife ein:
    Code:
    while read line; do
      ...
    done <datei
    Jan
    Danke, das probiere ich mal aus

Lesezeichen

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •