2016-05-14 11 views
10

Próbuję dowiedzieć się, jak wykonać następujące czynności z sed:Formatowanie IP z sed

Mam listę adresów IPv4 i staram się uczynić je wszystkie jednolite na wyświetlaczu. Na przykład: 1.2.4.32 będzie 001.002.004.032. 10.125.62.1 będzie 010.125.062.001.

Próbuję użyć sed, aby to zrobić, ponieważ tego właśnie się uczę właśnie teraz.

Mam te dwa, które przyjmą jedną lub dwie cyfry i dopiszą zera na początku.

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

Ale to ma bardziej praktyczny problem, ponieważ mój plik wejściowy będzie miał pojedyncze lub podwójne cyfry w innych miejscach poza adresem IP. Przykład:

host-1 1.2.3.32 

Więc potrzebny jest sposób na to, aby spojrzeć na pełny adres IP, co uważałem, że można osiągnąć za pomocą tej

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

ale nie tylko, że ignorowanie przypadek 1.something.something.something, ale także dołącza 00 na końcu 3 oktetu z jakiegoś powodu. Plik

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

Próbka:

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

Czy zawartość pliku ma wzór? Opublikuj fragment z pliku – sjsam

+0

Zgodnie z życzeniem. plik –

+0

dziękuje, To sprawia, że ​​pytanie jest bardziej zrozumiałe :) – sjsam

Odpowiedz

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 

robi:

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 

daje:

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 

przewagę nad podejściem wymienionym przez @ Benjamin-w

Można wymienić wiele adresów IP w taki sam linia

Wada (podejście wspomniał @ Benjamin-w środek tego)

Gdyby tam być słowo powiedzieć Node-000234 byłoby zmienić na Node-234. W rzeczywistości można pracować nad drugim poleceniem zastępowania, aby uzyskać pożądane zachowanie.

+0

dzięki @sjsam, robi to wszystko doskonale. –

+0

@ D.Zou: pamiętaj o rzeczach, o których wspomniałem w końcu :) – sjsam

+0

@sjsam Advantage number 2 już nie ma;) –

5

idiomatyczne sposobem zmiany tylko części linii jest, aby skopiować go do miejsca przechowywania, usunięcia części nie jesteśmy zainteresowani z przestrzeń wzoru, odzyskaj przestrzeń do przechowywania, a następnie zmień przestrzeń wzorów, aby zastąpić część, którą zmieniliśmy nową wersją.

ten powinien działać (zastąpić -r z -E dla BSD sed):

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 

Ostatnim krokiem jest najbardziej skomplikowana. Tuż przed nim, linia wygląda następująco (znak nowej linii, jak \n końcowej linii jako $):

010.020.005.126\nJumpstart Server jumo  10.20.5.126$ 

czyli nasz nowy i ulepszony adres IP, znak nowej linii, a następnie pełna starej linii. Teraz uchwycić Podkreślone grupy:

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

i zmienić linię za pomocą grupy 2, a następnie grupy 1 (nasz nowy IP) i 4. Należy zauważyć, że

  • Istnieją cztery grupy przechwytywania, ale Trzeci jest po to, aby pomóc w opisaniu adresu IP, tak naprawdę nie chcemy go zachować, stąd \2\1\4 w podstawieniu (nie ma żadnych grup przechwytujących w sed).
  • Ostatnia grupa przechwytywania (po adresie IP) jest pusta, ale jej posiadanie umożliwia korzystanie z niej w przypadku linii, które mają adres IP w dowolnym miejscu.
  • To zastępuje tylko pierwszy adres IP w każdej linii, na wypadek, gdyby było ich kilka.

Ogólny wynik jest

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 

taka sama jak solidnie nieczytelne jedną wkładką:

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 jest rozszerzeniem GNU. Skrypt działa również bez niego; używając go, zapewnia się, że blah1.2.3.4blah pozostaje sam.

+1

@cyrus oops ... Na to! –

+1

@cyrus Tam. 's/[0-9] ([0-9] {3})/\ 1/g' musi mieć postać' s/[0-9] * ([0-9] {3})/\ 1/g'. Tyle o wewnętrznej kontroli jakości z mojej strony! ;) –

+0

'-E' faktycznie działa na GNU sed, po prostu nieudokumentowane. – andlrc