내 문자열(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 주소(또는 마스크)의 점으로 구분된 십진수 형태를 단순 정수로 변환i2d()
반대 작업을 수행합니다. 간단한 정수를 점으로 구분된 십진수로 변환합니다.ipmask()
단순히 주소와 넷마스크의 비트별 AND를 계산하면 주소의 네트워크 부분이 제공됩니다. Bash는 피연산자가&
정수일 것으로 예상합니다.
이 두 호출은 ipmask
서로 다른 두 개의 마스킹된 IP 주소를 기반으로 네트워크를 계산하는 방법을 보여줍니다.
질문에 명시된 바와 같이123.444.888.235
잘못된 IP 주소입니다. 대신에 이러한 예를 사용했습니다 123.44.88.235
.
답변4
또 다른 sed
답변:
sed -r 's/(.*\.).*/\10/'
마지막 점까지 모든 것을 그룹화하고 전체 줄을 해당 그룹의 내용으로 바꾼 다음 0을 붙입니다.
대괄호를 이스케이프 처리하지 않으려면 -r을 사용합니다.