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 bash
veya başka bir kabuk komut dosyası dilinde yapabilirim?
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 bash
veya başka bir kabuk komut dosyası dilinde yapabilirim?
Yanıtlar:
Herhangi bir POSIX kabuğunda:
var=123.444.888.235
new_var="${var%.*}.0"
${var%pattern}
ksh
80'lerde tanıtılan , POSIX tarafından standart sh
dil 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 $var
maçları en kısa dize elimden desen bunun sonunda (veya aynı şekilde kapalı $var
ki eğer desen uymuyor). Yani ${var%.*}
( nokta ve ardından herhangi bir sayıda karakter anlamına gelen .*
bir desen nerede ) $var
en 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
.
${var%.*}
man bash
ve enter tuşuna basın, sonra yazın /suffix pattern
ve enter tuşuna basın. :)
new_var="${var%.*}.0"
... nJoy !.
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='.'
$NF
1;
awk
$ echo 123.444.888.235 | perl -pe 's/\d+$/0/'
123.444.888.0
-p
Söyler perl
verdiğ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 bash
veya zsh
gibi), 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
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.0
ağ 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üri2d()
tersini yapar - basit bir tamsayıyı noktalı ondalık sayıya dönüştürüripmask()
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.235
geçersiz bir IP adresidir. Bunun 123.44.88.235
yerine bu örnekler için kullandım .