简化bash中的CIDR列表

时间:2015-02-08 06:53:12

标签: bash

我正在尝试为Google的计算机创建一个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上运行它。

2 个答案:

答案 0 :(得分:1)

我能够在ipcalc的帮助下解决它。没有ipcalc,它会变得更加乏味。用for替换while可以加快速度。鉴于我的答案是正在进行的工作,我不是在赞美自己的观点:

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 '%d\n' "$((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
}

答案 1 :(得分:0)

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,并使用扩展pattern matching在累积列表中搜索网络来实现此目的{{ 1}}(超级)网络,如果没有超网模式匹配,则输出网络并将其添加到列表中。