Bash'taki son noktadan sonra dizeyi değiştir


12

Bir dize (IP adresi) aşağıdaki desen var:

123.444.888.235

Noktadan sonra son sayıyı değiştirmek istiyorum 0, böylece olur:

123.444.888.0

Nasıl bashveya başka bir kabuk komut dosyası dilinde yapabilirim?


1
Bu teller nerede? Bir bash değişkeninde? Bir metin dosyasında her satıra bir tane mi?
Stéphane Chazelas

Bir değişkendir. Maalesef bundan bahsetmeyi unuttum.
Ari

3
Bunlar IP adresleri ise, 444 ve 888 geçersiz sekizli değerleridir.
Dijital Travma

Yanıtlar:


24

Herhangi bir POSIX kabuğunda:

var=123.444.888.235
new_var="${var%.*}.0"

${var%pattern}ksh80'lerde tanıtılan , POSIX tarafından standart shdil için standartlaştırılan ve şimdi de bu dili yorumlayan tüm kabuklar tarafından uygulanan bir operatördür bash.

${var%pattern}içeriğiyle genişlediğinde $varmaçları en kısa dize elimden desen bunun sonunda (veya aynı şekilde kapalı $varki eğer desen uymuyor). Yani ${var%.*}( nokta ve ardından herhangi bir sayıda karakter anlamına gelen .*bir desen nerede ) $varen sağa .ve onu izleyene kadar genişler . Aksine, en uzun kalıpla eşleşen dize kadar genişleyip sıyrılmıştır en sol olmadan ve ne onu takip eder. ${var%%.*}$var.


Nedir ? ${var%.*}
sesler

@ tjt263 yazın, komut satırı yazın man bashve enter tuşuna basın, sonra yazın /suffix patternve enter tuşuna basın. :)
Wildcard

Yazınızı takip eden bazı alıntılar eklendi : new_var="${var%.*}.0"... nJoy !.

8

Bu çalışmalı.

echo 123.444.888.235 | sed 's/\([0-9]*\.[0-9]*\.[0-9]*\.\)[0-9]*/\10/'

Son sedikame alanının ,, değişmez bir sıfırla birleştirilen \10ilk eşleşen desen ( \1) olduğunu unutmayın.


5

Birkaç yol (bunların tümü, dizedeki son sayı kümesini değiştirmek istediğinizi varsayar):

$ echo 123.444.888.235 | awk -F'.' -vOFS='.' '{$NF=0}1;'
123.444.888.0

Burada girdi alanı ayırıcısı olarak kullanmayı ve çıktı alanı ayırıcısı olarak kullanmayı -F'.'söyler . Sonra, biz sadece son alanı (set 0'a) ve (çizgi yazdırmak olduğunu stenografi "Mevcut hattı basmak" şeklinde).awk.-vOFS='.'$NF1;awk

$ echo 123.444.888.235 | perl -pe 's/\d+$/0/'
123.444.888.0

-pSöyler perlverdiği komut uygulandıktan sonra her bir giriş hattını yazdırmak için -e. Komut dosyasının kendisi, satırın sonunda bir veya daha fazla sayının yerini alacak basit bir ikame operatörüdür 0.

$ echo 123.444.888.235 | sed 's/[0-9]*$/0/'
123.444.888.0

Aynı fikir sed, [0-9]yerine kullanmak \d.


Dizeniz bir değişkendeyse ve burada dizeleri destekleyen bir kabuk kullanıyorsanız (örneğin bashveya zshgibi), yukarıdakileri şu şekilde değiştirebilirsiniz:

awk -F'.' -vOFS='.' '{$NF=0}1;' <<<$var
perl -pe 's/\d+$/0/' <<<$var
sed 's/[0-9]*$/0/' <<<$var

5

Bir IP adresine ağ maskesi uygulamak için genel durum:

Girişinizin bir IP adresi olduğu ve bu adresin son sekizlisini değiştirdiğiniz göz önüne alındığında .0, gerçekten elde etmeye çalıştığınız şeyin , 255.255.255.0ağ maskesini kullanarak IP adresinin ağ kısmını hesaplamak olduğunu varsayıyorum .

Ağ maskesi uzunluğunuz 8 ile bölünebiliyorsa, sekizlileri sıfırlarla değiştirmek sorun olmaz, ancak bu genel durum değildir. Herhangi bir geçerli (alt ağ) ağ maskesi için bu işlemi gerçekleştirmeniz gerekiyorsa, böyle bir şey yapabilirsiniz:

function d2i() {
    echo $(( 0x$( printf "%02x" ${1//./ } ) ))
}

function i2d() {
    h=$( printf "%08X" "$1" )
    echo $(( 0x${h:0:2} )).$(( 0x${h:2:2} )).$(( 0x${h:4:2} )).$(( 0x${h:6:2} ))
}

function ipmask() {
    i2d $(( $( d2i $1 ) & $( d2i $2 ) ))
}

ipmask 123.44.88.235 255.255.255.0     # outputs 123.44.88.0
ipmask 123.44.88.235 255.255.255.240   # outputs 123.44.88.224

Bu 3 işlevi tanımlar:

  • d2i() IP adresinin (veya maskenin) ondalık ondalık biçimini basit bir tamsayıya dönüştürür
  • i2d() tersini yapar - basit bir tamsayıyı noktalı ondalık sayıya dönüştürür
  • ipmask()bir adresin ağ kısmını vermek için bir adresin ve bir ağ maskesinin bitsel VE bir değerini hesaplar. Bash, işlenenlerin &tamsayı olmasını bekler .

İki çağrı ipmask, ağın iki farklı maske için bir IP adresinden nasıl hesaplanabileceğini gösterir.


Soruda belirtildiği gibi, 123.444.888.235geçersiz bir IP adresidir. Bunun 123.44.88.235yerine bu örnekler için kullandım .


0

Alternatif bir sedcevap:

sed -r 's/(.*\.).*/\10/'

Her şeyi son noktaya kadar gruplandırır ve tüm satırı grubun içeriği ve ardından 0
ile değiştirir. Parantezlerden kaçmak zorunda kalmamak için -r kullanıyorum.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.