구문을 사용하여 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
솔루션을 작성했습니다 .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"
이건 좀 투박해요. 이는 두 개의 일회성 변수를 정의하며 더 많은 부분(예: 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
배쉬에서는 불가능합니다.