2016-05-14 20 views
10

Ich versuche, herauszufinden, wie die folgenden mit sed zu tun:Formatierung IP mit sed

ich eine Liste von IPv4-Adressen bekommen, und ich versuche, sie alle einheitlich in der Anzeige zu machen. Also zum Beispiel: 1.2.4.32 wäre 001.002.004.032. 10.125.62.1 wäre 010.125.062.001.

Ich versuche sed zu verwenden, weil das genau das ist, was ich gerade lerne.

Ich habe diese zwei, die jede ein oder zweistellige Zahl nehmen und Nullen an der Vorderseite anhängen.

sed 's/\<[0-9][0-9]\>/0&/g' file 
sed 's/\<[0-9]\>/00&/g' file 

Aber das läuft in einem praktischeren Problem, dass meine Eingabedatei ein- oder zweistelligen Zahlen in anderen Nicht-IP-Adresse platziert haben. Beispiel:

host-1 1.2.3.32 

Also muss ich einen Weg für sie für die volle IP-Adresse zu suchen, die ich dachte, könnte dieses

sed 's/\.\<[0-9]\>/00&/g' 

erreicht werden, aber nicht nur, dass der Fall von 1.something.something.something nicht ignorieren, aber es hängt auch die 00 am Ende des 3. Oktetts aus irgendeinem Grund.

echo "10.10.88.5" | sed 's/\.\<[0-9]\>/00&/g' 
10.10.8800.5 

Beispieldatei:

Jumpstart Server jumo  10.20.5.126 
Jumpstart Server acob  10.20.5.168 
NW1 H17 Node cluster  10.10.161.87 
NW1 H17 Node-1  10.10.161.8 
NW1 H17 Node-2  10.10.161.9 
ts-nw1  10.10.8.6 
+0

Hat der Inhalt der Datei ein Muster? Veröffentlichen Sie einen Auszug aus der Datei – sjsam

+0

Wie gewünscht. die Datei –

+0

danke, Das macht die Frage klarer :) – sjsam

Antwort

3
$ cat 37222835.txt 
Jumpstart Server jumo  10.20.5.126 10.29.23.24 
Jumpstart Server acob  10.20.5.168 dig opt 
Jumpstart Server reac  251.218.212.1 rel 
NW1 H17 Node cluster  10.10.161.87 
NW1 H17 Node-1  10.10.161.8 
NW1 H17 Node-2  10.10.161.9 
ts-nw1  10.10.8.6 
Nw2 HW12 Node-3  192.168.0.1 
cluster 

tun:

sed -n 's/\([1]\?[0-9][0-9]\?\|2[0-4][0-9]\|25[0-5]\)\{1\}\.'\ 
'\([1]\?[0-9][0-9]\?\|2[0-4][0-9]\|25[0-5]\)\{1\}\.'\ 
'\([1]\?[0-9][0-9]\?\|2[0-4][0-9]\|25[0-5]\)\{1\}\.'\ 
'\([1]\?[0-9][0-9]\?\|2[0-4][0-9]\|25[0-5] \)/00\1\.00\2\.00\3\.00\4/g; 
s/0\+\([0-9]\{3\}\)/\1/g;p' 37222835.txt 

gibt:

Jumpstart Server jumo  010.020.005.126 010.029.023.024 
Jumpstart Server acob  010.020.005.168 dig opt 
Jumpstart Server reac  251.218.212.001 rel 
NW1 H17 Node cluster  010.010.161.087 
NW1 H17 Node-1  010.010.161.008 
NW1 H17 Node-2  010.010.161.009 
ts-nw1  010.010.008.006 
Nw2 HW12 Node-3  192.168.000.001 
cluster 

Vorteil gegenüber dem Ansatz erwähnt von @ benjamin-w

Diese mehrere IP-Adressen im selben ersetzen Linie

Nachteil (der Ansatz erwähnt von @ benjamin-w abzuhelfen)

dort hatte sein Wort sagen Node-000234 es Node-234 geändert würde. In der Tat könnten Sie am zweiten Ersetzungsbefehl arbeiten, um das gewünschte Verhalten zu erhalten.

+0

Dank @sjsam, das macht alles perfekt. –

+0

@ D.Zou: bedenken Sie die Sachen, die ich zuletzt erwähnt habe :) – sjsam

+0

@sjsam Vorteil Nummer 2 ist jetzt weg;) –

5

Der idiomatische Weg nur Teile einer Linie zu ändern ist es in den Halteraum zu kopieren, entfernen Sie die Teile, die wir in von der nicht interessiert Pattern Space, hole den Hold-Space zurück und ordne den Pattern-Space neu, um den Teil zu ersetzen, den wir mit unserer neuen Version geändert haben.

Dies sollte funktionieren (-r mit -E für BSD sed ersetzen):

sed -r 'h     # Copy pattern space to hold space 

# Remove everything except IP address from pattern space 
s/.*\b(([0-9]{1,3}\.){3}[0-9]{1,3})\b.*/\1/ 

s/([0-9])+/00&/g   # Prepend '00' to each group of digits 
s/[0-9]*([0-9]{3})/\1/g # Only retain last three digits of each group 
G       # Append hold space to pattern space 

# Replace old IP with new IP 
s/(.*)\n(.*)\b([0-9]{1,3}\.){3}[0-9]{1,3}\b(.*)/\2\1\4/' infile 

Der letzte Schritt ist die komplizierteste. Kurz bevor es sieht eine Zeile wie diese (Newline als \n, Zeilenende als $):

010.020.005.126\nJumpstart Server jumo  10.20.5.126$ 

das heißt unsere neue und verbesserte IP-Adresse, ein Newline, dann die komplette alte Linie. Wir fangen jetzt die unterstrichenen Gruppen:

010.020.005.126\nJumpstart Server jumo  10.20.5.126$ 
^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^   ^
     (.*)  \n   (.*)    \b...\b (.*) 
     \1     \2     \3  \4 

und die Zeile neu anordnen, indem 2 mit Gruppe, dann die Gruppen 1 (unsere neue IP) und 4. Beachten Sie, dass

  • Es gibt vier Einfanggruppen, aber die das dritte ist nur da, um eine IP-Adresse zu beschreiben, wir wollen es eigentlich nicht behalten, daher \2\1\4 in der Substitution (es gibt keine nicht-einfangenden Gruppen in sed).
  • Die letzte erfassende Gruppe (nach der IP-Adresse) ist leer, aber mit ihr ist es möglich, diese für Leitungen zu verwenden, die irgendwo die IP-Adresse haben.
  • Dies ersetzt nur die erste IP-Adresse in jeder Zeile, falls es mehrere gibt.

Die Gesamtleistung ist

Jumpstart Server jumo  010.020.005.126 
Jumpstart Server acob  010.020.005.168 
NW1 H17 Node cluster  010.010.161.087 
NW1 H17 Node-1  010.010.161.008 
NW1 H17 Node-2  010.010.161.009 
ts-nw1  010.010.008.006 

das gleiche wie ein soliden unleserlich Einzeiler:

sed -r 'h;s/.*\b(([0-9]{1,3}\.){3}[0-9]{1,3})\b.*/\1/;s/([0-9])+/00&/g;s/[0-9]*([0-9]{3})/\1/g;G;s/(.*)\n(.*)\b([0-9]{1,3}\.){3}[0-9]{1,3}\b(.*)/\2\1\4/' infile 

\b eine GNU-Erweiterung ist. Das Skript funktioniert meistens auch ohne es; die Verwendung stellt sicher, dass blah1.2.3.4blah in Ruhe gelassen wird.

+1

@cyrus oops ... Darauf! –

+1

@cyrus Dort. 's/[0-9] ([0-9] {3})/\ 1/g' musste' s/[0-9] * sein ([0-9] {3})/\ 1/g'. So viel zur internen Qualitätssicherung meinerseits! ;) –

+0

'-E' funktioniert tatsächlich auf GNU sed, einfach undokumentiert. – andlrc