
私の文字列(IPアドレス)には次のパターンがあります。
123.444.888.235
0
ドットの後の最後の数字を次のように変更したいと思います。
123.444.888.0
bash
シェルスクリプトや他の言語を使用してこれを行うにはどうすればよいですか?
答え1
POSIXシェルでは:
var=123.444.888.235
new_var="${var%.*}.0"
${var%pattern}
ksh
は1980年代に導入された演算子で、sh
POSIXで標準言語に標準化されており、現在はbash
。
${var%pattern}
$var
最短一致文字列の内容をストリップに拡張模様終わりを離れる(または$var
そのように模様不一致)。だから${var%.*}
(どこ.*
?模様つまり、ドットの後に任意の数の文字が続く場合)は、右端のポイントを超えて$var
拡張されません.
。対照的${var%%.*}
に、最長削除されたパターンに一致する文字列は、左端以降の内容が
$var
ないように拡張されます。.
答え2
これはうまくいきます。
echo 123.444.888.235 | sed 's/\([0-9]*\.[0-9]*\.[0-9]*\.\)[0-9]*/\10/'
最後のsed
代替フィールドは、リテラル0に関連付けられた\10
最初の一致パターン()です。\1
答え3
IPアドレスにネットワークマスクを適用する一般的な場合:
IPアドレスを入力し、アドレスの最後のオクテットを次に置き換えたとします.0
。本物試みられているのは、ネットマスクを使用してIPアドレスのネットワーク部分を計算することです255.255.255.0
。
ネットマスクの長さを8で割ることができる場合、オクテットを0に変更すると問題は解決しますが、一般的なものではありません。有効な(サブネット)ネットマスクに対してこれを行う必要がある場合は、次のことができます。
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
これは3つの機能を定義します。
d2i()
IPアドレス(またはマスク)の点で区切られた10進形式を単純整数に変換するi2d()
反対の作業を行います。単純な整数をドットで区切られた10進数に変換します。ipmask()
単にアドレスとネットマスクのビットごとのANDを計算すると、アドレスのネットワーク部分が提供されます。 Bashはオペランドが整数である&
と予想します。
これら2つの呼び出しは、2つのipmask
異なるマスクされたIPアドレスに基づいてネットワークを計算する方法を示しています。
質問で述べたように123.444.888.235
無効なIPアドレスです。代わりにこれらの例を使用しました123.44.88.235
。
答え4
もう一つのsed
答え:
sed -r 's/(.*\.).*/\10/'
最後のポイントまですべてをグループ化し、行全体をそのグループの内容に置き換えて0を付けます。
角かっこをエスケープしない場合は、-rを使用します。