我正试图为谷歌的计算机创建一个CIDR列表。当我在Linux中发布whois -h whois.radb.net -- '-i origin AS15169' | grep ^route: | sed 's/.* //'
。这个清单太长太多余了。例如,在最后,我看到:
216.239.58.0/23
216.239.58.0/24
216.239.59.0/24
216.239.60.0/23
216.239.60.0/24
216.239.61.0/24
216.239.62.0/23
216.239.62.0/24
216.239.63.0/24
这些都是上面几个屏幕列出的子网216.239.32.0/19
的一部分。
Bash中有没有一种简单的方法可以减少行数?搜索SO,我发现了一些Python的一行代码,但如果可能的话,我想在Bash上运行它。
我能够在ipcalc
的帮助下解决它。如果没有ipcalc,它会变得更加乏味。用while
替换for
应该会加快速度。我不会给自己打分,因为我的答案是一项正在进行的工作:
lowestipinrange()
{
ipcalc "$1" | grep HostMin | sed 's/HostMin: *//'| sed 's/ .*//'
}
highestipinrange()
{
ipcalc "$1" | grep HostMax | sed 's/HostMax: *//'| sed 's/ .*//'
}
ip2dec () {
# This is verbatim from https://stackoverflow.com/questions/10768160/ip-address-converter
local a b c d ip=$@
IFS=. read -r a b c d <<< "$ip"
printf '%dn' "$((a * 256 ** 3 + b * 256 ** 2 + c * 256 + d))"
}
as2ip()
{
ALLSUBNETS=$(whois -h whois.radb.net -- '-i origin '$1 | grep ^route: | sed 's/.* //' | sort -k 2 -t '/')
USEFULSUBNETS=()
MINIPARRAY=()
MAXIPARRAY=()
COUNTUSEFULNETS=0
for subnet in $ALLSUBNETS ; do
CURRMINIP=`lowestipinrange $subnet`
CURRMINIP=`ip2dec $CURRMINIP`
CURRMAXIP=`highestipinrange $subnet`
CURRMAXIP=`ip2dec $CURRMAXIP`
SUBNETSEEMSUSEFUL=true
for ((i = 0; i < $COUNTUSEFULNETS ; i++)); do
if (( ${MINIPARRAY[$i]} <= $CURRMINIP )) && (( ${MAXIPARRAY[$i]} >= $CURRMAXIP )) ; then
SUBNETSEEMSUSEFUL=false
fi
done
if [ "$SUBNETSEEMSUSEFUL" = true ]; then
let "COUNTUSEFULNETS += 1"
MINIPARRAY+=($CURRMINIP)
MAXIPARRAY+=($CURRMAXIP)
USEFULSUBNETS+=("$subnet")
fi
done
for ((i = 0; i < $COUNTUSEFULNETS ; i++)); do
echo ${USEFULSUBNETS[$i]}
done
}
shopt -s extglob
IFS=|$IFS
while IFS=./ read a b c d e
do ip=$(printf %08i `bc <<<"obase=2;$a;$b;$c;$d"`)
network=${ip::$e}*
[[ "$network" == !($netlist) ]] &&
nets[${#nets[*]}]="$network" netlist="${nets[*]}" && echo $a.$b.$c.$d/$e
done
此脚本输出不属于以前看到的网络的网络地址。它通过将输入CIDR表示法转换为仅包括网络前缀的二进制数字(0和1)的字符串$network
,并使用扩展模式匹配来在(超级)网络的累积列表$netlist
中搜索网络,输出网络并将其添加到列表中(如果与超网模式不匹配)。