# helper to convert hex to dec (portable version)
hex2dec(){
[ "$1" != "" ] && printf "%d" "$(( 0x$1 ))"
}
# expand an ipv6 address
expand_ipv6() {
ip=$1
# prepend 0 if we start with :
echo $ip | grep -qs "^:" && ip="0${ip}"
# expand ::
if echo $ip | grep -qs "::"; then
colons=$(echo $ip | sed 's/[^:]//g')
missing=$(echo ":::::::::" | sed "s/$colons//")
expanded=$(echo $missing | sed 's/:/:0/g')
ip=$(echo $ip | sed "s/::/$expanded/")
fi
blocks=$(echo $ip | grep -o "[0-9a-f]\+")
set $blocks
printf "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n" \
$(hex2dec $1) \
$(hex2dec $2) \
$(hex2dec $3) \
$(hex2dec $4) \
$(hex2dec $5) \
$(hex2dec $6) \
$(hex2dec $7) \
$(hex2dec $8)
}
我还有这个功能可以压缩
# returns a compressed ipv6 address under the form recommended by RFC5952
compress_ipv6() {
ip=$1
blocks=$(echo $ip | grep -o "[0-9a-f]\+")
set $blocks
# compress leading zeros
ip=$(printf "%x:%x:%x:%x:%x:%x:%x:%x\n" \
$(hex2dec $1) \
$(hex2dec $2) \
$(hex2dec $3) \
$(hex2dec $4) \
$(hex2dec $5) \
$(hex2dec $6) \
$(hex2dec $7) \
$(hex2dec $8)
)
# prepend : for easier matching
ip=:$ip
# :: must compress the longest chain
for pattern in :0:0:0:0:0:0:0:0 \
:0:0:0:0:0:0:0 \
:0:0:0:0:0:0 \
:0:0:0:0:0 \
:0:0:0:0 \
:0:0; do
if echo $ip | grep -qs $pattern; then
ip=$(echo $ip | sed "s/$pattern/::/")
# if the substitution occured before the end, we have :::
ip=$(echo $ip | sed 's/:::/::/')
break # only one substitution
fi
done
# remove prepending : if necessary
echo $ip | grep -qs "^:[^:]" && ip=$(echo $ip | sed 's/://')
echo $ip
}
您可以将它们组合起来测试给定的输入是否是ipv6。
# a valid ipv6 is either the expanded form or the compressed one
is_ipv6(){
expanded="$(expand_ipv6 $1)"
[ "$1" = "$expanded" ] && return 0
compressed="$(compress_ipv6 $expanded)"
[ "$1" = "$compressed" ] && return 0
return 1
}
6条答案
按热度按时间cnwbcb6i1#
使用
sipcalc
可以做到这一点。它提供了比你需要的更多的信息,但是一点grep
和cut
可以解决这个问题:-)作为参考,这是
sipcalc
的完整输出:bvuwiixz2#
我最近想要一个无依赖性的解决方案,它可以跨shell移植,并可以在openwrt等平台上工作。我想出了以下片段:
我还有这个功能可以压缩
您可以将它们组合起来测试给定的输入是否是ipv6。
我希望这有帮助!这些代码片段取自https://github.com/chmduquesne/wg-ip。如果您发现任何bug,请贡献!
klr1opcd3#
euoag5mw4#
使用awk,你可以这样做:
对awk的第一次调用在“::“之间添加缺少的零和冒号;对awk的第二次调用将缺少的0添加到每个组。
要修剪冒号,只需将最后一个OFS=":“替换为OFS=""。
wswtfjt75#
这个可以吗?
zqdjd7g96#
POSIX shell解决方案:
测试:
这是一个基于this answer by user48768的稍微改进的版本,他从这个github source复制了它,其中:
__expand_ipv6_
-prefix)注意:
expand_ipv6
函数需要一个有效的IPv6地址,否则结果也不一定有效。要测试字符串是否是有效的IPv6地址,请用途:此外,为了压缩IPv6地址(与expand_ipv6相反),这里还有一个改进的解决方案: