Mam następujący ciąg w ciągu (adres IP):
123.444.888.235
Chcę zastąpić ostatni numer po kropce 0
, więc staje się:
123.444.888.0
Jak mogę to zrobić w bash
innym języku skryptowym powłoki?
bash
shell-script
string
Ari
źródło
źródło
Odpowiedzi:
W dowolnej powłoce POSIX:
${var%pattern}
jest operatorem wprowadzonymksh
w latach 80., znormalizowanym przez POSIX dla standardowegosh
języka i teraz zaimplementowanym przez wszystkie powłoki, które interpretują ten język, w tymbash
.${var%pattern}
rozwija się do zawartości$var
pozbawionego najkrótszego łańcucha, który pasuje do wzorca na jego końcu (lub do tego samego,$var
jakby ten wzór nie pasował). Tak więc${var%.*}
(gdzie.*
jest wzorzec oznaczający kropkę, po której następuje dowolna liczba znaków) rozwija się$var
bez znaku najbardziej po prawej.
i co następuje po nim. W przeciwieństwie do tego,${var%%.*}
gdy najdłuższy ciąg pasujący do wzoru zostanie rozebrany, rozwinąłby się$var
bez skrajnego lewego.
i tego, co następuje po nim.źródło
${var%.*}
man bash
i naciśnij enter, następnie wpisz/suffix pattern
i naciśnij enter. :)new_var="${var%.*}.0"
... nJoy !.To powinno działać.
Zauważ, że ostatnim polem
sed
podstawienia\10
jest pierwszy dopasowany wzorzec (\1
), połączony dosłownie zerem.źródło
Kilka sposobów (wszystkie zakładają, że chcesz zmienić ostatni zestaw liczb w ciągu):
Tutaj
-F'.'
mówi,awk
aby użyć.
jako separatora pola wejściowego i-vOFS='.'
użyć go jako separatora pola wyjściowego. Następnie po prostu ustawiamy ostatnie pole ($NF
) na 0 i wypisujemy linię (1;
toawk
skrót od „print the current line”).-p
Mówiperl
wydrukować każdą linię wejściowego po zastosowaniu skryptu podane przez-e
. Sam skrypt jest po prostu prostym operatorem podstawiania, który zastąpi jedną lub więcej liczb na końcu wiersza0
.Ten sam pomysł w
sed
, używając[0-9]
zamiast\d
.Jeśli twój ciąg jest w zmiennej i używasz powłoki, która obsługuje tutaj ciągi (takie jak
bash
lubzsh
na przykład), możesz zmienić powyższe na:źródło
Ogólny przypadek zastosowania maski sieci do adresu IP:
Biorąc pod uwagę, że wpisujesz adres IP i zastępujesz ostatni oktet tego adresu
.0
, zakładam, że naprawdę próbujesz obliczyć część sieciową adresu IP za pomocą255.255.255.0
maski sieci.Zwykłe zastąpienie oktetów zerami jest OK, jeśli długość maski sieci jest podzielna przez 8, ale nie jest to ogólny przypadek. Jeśli kiedykolwiek będziesz musiał wykonać tę operację dla dowolnej prawidłowej maski sieci (podsieci), możesz zrobić coś takiego:
Definiuje to 3 funkcje:
d2i()
konwertuje kropkowo-dziesiętną postać adresu IP (lub maski) na prostą liczbę całkowitąi2d()
robi coś przeciwnego - konwertuje zwykłą liczbę całkowitą na kropkę dziesiętnąipmask()
po prostu oblicza bitowo ORAZ adresu i maski sieci, aby podać część adresu w sieci. Bash oczekuje, że operandy&
będą liczbami całkowitymi.Dwa połączenia
ipmask
pokazują, jak można obliczyć sieć z adresu IP dla dwóch różnych masek.Uwaga: jak podano w pytaniu,
123.444.888.235
to nieprawidłowy adres IP. Użyłem123.44.88.235
zamiast tego dla tych przykładów.źródło
Alternatywna
sed
odpowiedź:Grupuje wszystko do ostatniej kropki i zastępuje pełną linię treścią grupy, po której następuje 0.
Używam -r, aby uniknąć konieczności ucieczki w nawiasy.
źródło