Bash:IPv4アドレスの4つの部分のうちの1つを抽出する

Bash:IPv4アドレスの4つの部分のうちの1つを抽出する

構文を使用して、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ソリューションを作成しました。sedcut

今私の質問は:より簡単な解決策はありますか?パラメータ拡張配列と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私の最初の解決策(上記)で合計の代わりに変数名を選択しましたlast3last2
  • declare sec"$count"="value"sec1は、、when、、、およびに割り当てられたsec2方法です。似ていますが、より安全です。sec3sec4count1234eval
  • これvalue、、、私の元の答えが、および"${slice%%.*}"に割り当てた値に似ています。firstsecondthird

答え4

zsh を使用すると、パラメーター置換を入れ子にできます。

$ ip=12.34.56.78
$ echo ${${ip%.*}##*.}
56
$ echo ${${ip#*.}%%.*}
34

バッシュでは不可能です。

関連情報