
構文を使用して、IPv4アドレスの最後の部分と最初の部分を抽出でき${var##pattern}
ます${var%%pattern}
。
IP=109.96.77.15
echo IP: $IP
echo 'Extract the first section using ${var%%pattern}: ' ${IP%%.*}
echo 'Extract the last section using ${var##pattern}: ' ${IP##*.}
パラメータ拡張を使用してIPv4アドレスの2番目または3番目の部分をどのように抽出できますか?
これが私の解決策です。配列を使用してIFS変数を変更します。
:~/bin$ IP=109.96.77.15
:~/bin$ IFS=. read -a ArrIP<<<"$IP"
:~/bin$ echo ${ArrIP[1]}
96
:~/bin$ printf "%s\n" "${ArrIP[@]}"
109
96
77
15
また、およびコマンドを使用していくつかのawk
ソリューションを作成しました。sed
cut
今私の質問は:より簡単な解決策はありますか?パラメータ拡張配列とIFSの変更を使用しないものは何ですか?
答え1
IFSのデフォルト値を想定すると、次のように各オクテットを独自の変数に抽出できます。
read A B C D <<<"${IP//./ }"
または配列に入れます。
A=(${IP//./ })
答え2
あなたが一時的にオーバーライドしていないソリューションを具体的に要求したことを知っていますが、IFS
あなたが扱っていない素晴らしいシンプルなソリューションがあるので、
IFS=. ; set -- $IP
この短いコマンドは、IPアドレス要素をシェルの位置パラメータ $1
, $2
, $3
, .. ただし、元のファイルを最初に保存してから復元する必要が$4
あります。IFS
誰が知っていますか?おそらく、この回答は簡潔で効果的であるため、もう一度考えて受け入れます。
(以前はと誤って指定されましたIFS=. set -- $IP
。)
答え3
問題の説明は、意図したものよりも少し自由である可能性があります。脆弱性を悪用する危険がある場合、回避策は次のとおりです。ムルが言及:
first=${IP%%.*}
last3=${IP#*.}
second=${last3%%.*}
last2=${last3#*.}
third=${last2%.*}
fourth=${last2#*.}
echo "$IP -> $first, $second, $third, $fourth"
これはちょっとおっぱいです。これは2つのワンタイム変数を定義し、より多くの部分(MACまたはIPv6アドレスなど)を処理するために簡単に適応できません。 Sergey Kolodiaznyの答え上記の内容を次のように要約するようにインスピレーションを受けました。
slice="$IP"
count=1
while [ "$count" -le 4 ]
do
declare sec"$count"="${slice%%.*}"
slice="${slice#*.}"
count=$((count+1))
done
このセットsec1
、およびはsec2
次のようにsec3
確認できます。sec4
printf 'Section 1: %s\n' "$sec1"
printf 'Section 2: %s\n' "$sec2"
printf 'Section 3: %s\n' "$sec3"
printf 'Section 4: %s\n' "$sec4"
- ループ
while
はわかりやすくする必要があります。 4回繰り返されます。 - Sergiyは
slice
私の最初の解決策(上記)で合計の代わりに変数名を選択しましたlast3
。last2
declare sec"$count"="value"
sec1
は、、when、、、およびに割り当てられたsec2
方法です。似ていますが、より安全です。sec3
sec4
count
1
2
3
4
eval
- これ
value
、、、私の元の答えが、および"${slice%%.*}"
に割り当てた値に似ています。first
second
third
答え4
zsh を使用すると、パラメーター置換を入れ子にできます。
$ ip=12.34.56.78
$ echo ${${ip%.*}##*.}
56
$ echo ${${ip#*.}%%.*}
34
バッシュでは不可能です。