简化bash中的CIDR列表



我正试图为谷歌的计算机创建一个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中搜索网络,输出网络并将其添加到列表中(如果与超网模式不匹配)。

最新更新