Bash: IPv4 주소의 네 부분 중 하나 추출

Bash: IPv4 주소의 네 부분 중 하나 추출

구문을 사용하여 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 주소의 두 번째 또는 세 번째 부분을 어떻게 추출할 수 있습니까?

이것이 내 솔루션입니다. 배열을 사용하고 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"

이건 좀 투박해요. 이는 두 개의 일회성 변수를 정의하며 더 많은 부분(예: 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방법 입니다 . 비슷하지만 더 안전합니다.sec3sec4count1234eval
  • 이것value, , 는 내 원래 답변이 , 및 "${slice%%.*}"에 할당한 값과 유사합니다 .firstsecondthird

답변4

zsh를 사용하면 매개변수 대체를 중첩할 수 있습니다.

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

배쉬에서는 불가능합니다.

관련 정보