2014-03-27 313 views
2

我有一个原始文件与IP地址范围(xx.xx.xx. XX -yy.yy.yy. YY) 我想创建一个转换的范围的新名单到单个IP地址。 (所有的范围都在1-255范围)转换IP范围的IP地址

条件

(1)如在每行的第四个八比特组IP之间的差小于或等于最大
变量(比方说5 )它将循环并将每个迭代报告为单个/ 32地址。

(2)IP地址比最大变量更会被报告为/ 24

以下bash脚本工作正常,IP地址,但它是50000行的文件慢? 任何帮助,将不胜感激。它是其他功能的脚本的一部分,所以我需要留在BASH中。

for i in $data; do 

    A=$(echo $i | sed 's/-.*//'); B=$(echo $i | sed 's/^.*-//') 
    A1=$(echo $A | cut -d '.' -f 4); B1=$(echo $B | cut -d '.' -f 4) 
    diff=`expr $B1 - $A1` 

    if [ "$diff" == "0" ]; then 
      echo $A >> $outfile 
    elif [ "$diff" -gt "0" -a "$diff" -le $max ]; then 
      echo $A >> $outfile 
      for a in $(jot "$diff"); do 
        count=`expr $A1 + $a` 
        echo $A | sed "s/\.[0-9]*$/.$count/" >> $outfile 
      done 
    else 
      echo $A | sed 's/\.[0-9]*$/.0\/24/' >> $outfile 
    fi 
done 
+0

我建议使用已经有库来操纵ipv4地址的语言。不要重新发明轮子。 –

+0

@Glenn,你会怎么做这是“perl”。我可以从这个bash脚本中调用一个简短的perl脚本。 – CA171

+0

CPAN快速搜索“ip地址范围”显示https://metacpan.org/pod/Net::IPAddress::Util::Range看起来像它做你想做的。 –

回答

1

可能的原因你的脚本是50000这么慢行是你有bash调用大量的外部程序(sed,cut,jot,expr),在你的内部和外部循环的每次迭代中都会多次。当多次迭代复合时,分叉外部进程会增加大量时间开销。

如果你想在bash中做到这一点,并提高性能,你需要利用内置到bash中的等效功能。我为你的剧本刺了一针,并提出了这个问题。我试图保持的功能是相同的:

for i in $data; do 

    A="${i%-*}"; B="${i#*-}" 
    A1="${A##*.}"; B1="${B##*.}" 
    diff=$(($B1 - $A1)) 

    if [ "$diff" == "0" ]; then 
      echo $A >> $outfile 
    elif [ "$diff" -gt "0" -a "$diff" -le $max ]; then 
      echo $A >> $outfile 
      for ((a=1; a<=$diff; a++)); do 
        count=$(($A1 + $a)) 
        echo "${A%.*}.$count" >> $outfile 
      done 
    else 
      echo "${A%.*}.0/24" >> $outfile 
    fi 
done 

尤其是我做了很多使用的parameter expansionsarithmetic expansions的。我有兴趣看看这种加速比原来有什么样的加速(如果有的话)。我认为它应该快得多。

+0

哇。从5分钟到5秒。非常感谢!我必须使用Jot命令作为第二个“for循环”在sh中不起作用。它是一个pfSense Freebsd Box。 – CA171

+1

我想你可以用while循环替换'for $(jot)'并手动增加计数器。但我很高兴60倍的加速。 Upvotes将被优雅地接受:) –

0

如果你是好与使用python,安装(下载后,解压并运行sudo python setup.py install)IPADDR库https://pypi.python.org/pypi/ipaddr,然后写这样的事情

import ipaddr 
for ip in (ipaddr.IPv4Network('192.0.2.0/24')): 
    print ip