2017-08-14 2 views
0

ich diese Beispieldatei haben:Erhalten Sie mehrere Spiele von Text in geschweiften Klammern

authoritative; 

subnet x.x.x.x netmask x.x.x.x { 
    range x.x.x.x x.x.x.x; 
    deny unknown-clients; 
    default-lease-time 86400; 
    max-lease-time 86400; 
    option domain-name "bla"; 
    option domain-name-servers x.x.x.x; 
    option broadcast-address x.x.x.x; 
    option subnet-mask x.x.x.x; 
    option routers x.x.x.x; 

    host host1 { 
     hardware ethernet 00:e1:4c:68:00:53; 
     fixed-address 1.1.1.1; 
    } 

    host host2 { 
     hardware ethernet 01:e2:4d:69:01:54; 
     fixed-address 2.2.2.2; 
    } 

    host host3 { 
     hardware ethernet 02:e3:4e:70:02:55; 
     fixed-address 3.3.3.3; 
    } 

    host host4 { 
     hardware ethernet 03:e4:4f:71:03:56; 
     fixed-address 4.4.4.4; 
    } 

    host host5 { 
     hardware ethernet 04:e5:5f:72:04:57; 
     fixed-address 5.5.5.5; 
    } 
} 

Jetzt versuche ich, die MAC-Adresse und IP-Adresse Teile aus dem Inneren der Host x Blöcke zu extrahieren. Wenn ich diese Dateistruktur verwende (die newLines enthält), passt sie überhaupt nicht zusammen ... darauf werde ich später eingehen. Aber jetzt habe ich Schwierigkeiten, alle Spiele zu bekommen. Das ist, was ich bisher habe: Link to MyRegex Wie Sie dort sehen können, enthalten $ 1 und $ 2 die letzten Mac/IP-Adresse Einträge. Aber wie bekomme ich Übereinstimmungen für alle Einträge in der Beispieldatei? Ich bin sicher, ich vermisse etwas Wesentliches ...

Vielen Dank!

+1

Welche Sprache/Werkzeug? – Toto

+0

Da ich den Mechanismus einfach verstehen möchte, verwende ich dieses Online-Tool: http://regexr.com/. Am Ende werde ich versuchen, das Ergebnis mit Bash-Skript-Tools wie grep/awk/sed zu kombinieren. Aber jetzt versuche ich zu verstehen, wie man die Matches nur mit Regex vorbereiten kann - wenn das möglich ist – user2549803

+0

Danke, aber wie ich bereits erwähnt habe, möchte ich, dass dieses Muster nur in einem Host-Block gefunden wird – user2549803

Antwort

1
host.*?\{\s*hardware ethernet\s+(?:((?:[0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2});\s*fixed-address\s+((?:\d{1,3}.){3}\d{1,3}));\s*\} 

Tested here.


Erläuterungen

\s*\}\s*\} Sie wurden am Ende des Musters einer schließenden Klammer zu viele passen.

[0-255] übersetzt in beliebige Ziffern zwischen 0 und 2 oder 5. Nicht was Sie wollen. Es ist einfacher, einfach \d{1,3} hier zu verwenden.

\sfixed-address Sie benötigen \s*fixed-address hier, da Sie möglicherweise mehrere Leerzeichen vor fixed-address haben.

+0

Wow! Vielen Dank für die Erklärungen. Genau das, was ich wollte. – user2549803

+0

Ich habe noch eine Frage: Warum funktioniert diese Lösung nicht mit der gekürzten Version der Beispieldatei? Bitte schauen Sie sich [this] an (https: // regex101.com/r/cjuygq/1) Vielen Dank – user2549803

+0

Sie sollten wahrscheinlich die '. *' am Anfang der Regex entfernen. – pchaigno

1

Wow, deine Regex sieht übertrieben aus. Ein simplier wäre:

hardware ethernet ([0-9a-f:]+); fixed-address ([0-9\.]+);

es passt alle ips und MAC-Adressen. RegExr

+0

Sie haben völlig Recht . Aber wenn dieses Combo aus irgendeinem Grund außerhalb des Host-x-Codeblocks geschrieben wird, würde es auch diesem entsprechen. Deshalb wollte ich sicherstellen, dass die Übereinstimmungen nur im Host-Block-Kontext auftreten. Danke nochmal! – user2549803

1

können Sie explizit Teile der Zeichenfolge schreiben, um es einfacher zu machen, die man erfassen, als Sie derzeit haben:

(hardware ethernet [\da-f:]+;) (fixed-address [\d\.]+;) 

Auf diese Weise können zwei einfangende Gruppen, so dass Sie leicht die MAC-Adresse erhalten und die IP Adresse einzeln.

1

Da Sie erwähnt mit awk schließlich ist hier eine Arbeits awk:

awk '/^[ \t]*host /{hostblock=1; next} hostblock && /}/{hostblock=0} !hostblock{next} 
    {gsub(/;/, "", $NF)} /hardware ethernet/{mac[++i]=$NF} /fixed-address/{ip[++j]=$NF} 
END{for (k=1; k<i; k++) print mac[k], ip[k]}' file 

00:e1:4c:68:00:53 1.1.1.1 
01:e2:4d:69:01:54 2.2.2.2 
02:e3:4e:70:02:55 3.3.3.3 
03:e4:4f:71:03:56 4.4.4.4 
+0

Danke, und die Sed-Lösung würde wie folgt aussehen (https://stackoverflow.com/questions/45586363/parse-blocks-in-curly-brackets) – user2549803

+0

Sorry, aber 'sed' sollte nicht diese Art von tun wird bearbeitet. Dies ist, was "awk" gemacht wird, d. H. Um Textdateien Zeile für Zeile zu verarbeiten. – anubhava

Verwandte Themen