2014-08-31 60 views
1

我想在两个数组中找到部分匹配的ipv6前缀。例如,来自一个阵列的2001:db8:将与另一个阵列的2001:db8:1::/482001:db8:2::/48匹配。用正则表达式替换数组迭代

我已经拥有它通过遍历其它另一个阵列工作:

ru_routes=($(curl -4 ftp://ftp.ripe.net/ripe/stats/delegated-ripencc-latest | egrep -o '\|RU\|ipv6\|.+?::\|[0-9]+' | cut -d'|' -f4 | sed 's/::$/:/g')); 
msk_ix_routes=($(curl -4 http://www.msk-ix.ru/download/lg/msk_ipv6_pfx.txt.gz | gunzip | egrep -o '\b.*::/[0-9]*')); 
routes=(); 
for item1 in ${msk_ix_routes[@]}; do 
    for item2 in ${ru_routes[@]}; do 
     if [[ $item1 = $item2* ]]; then 
      routes+=($item1); 
      break 
     fi 
    done 
done 

但它的工作原理我MIPS路由器上有点慢(〜90秒)。我发现this useful answer,运行速度更快,但我无法使其与上面的工作方式相同。我不认为我需要“如果”建设,因为它会做同样的事情两次。我的非工作版本:

msk=" ${msk_ix_routes[*]} ";   # add framing blanks 

for item in ${ru_routes[@]}; do 
    routes+=(egrep -o "$item[\S]*/g" <<< $msk); 
done 

我猜这里有引用和转义的问题,但我无法解决它。请帮助)我愿意接受建议。

顺便说一下,我在它运行得更快第一个版本中使用的“无线”,但后来它精确匹配而已,所以我开始循环播放:

routes=($(comm -12 <(printf '%s\n' "${ru_routes[@]}" | LC_ALL=C sort) <(printf '%s\n' "${msk_ix_routes[@]}" | LC_ALL=C sort))); 
+0

无关的其他任何你想引用'[@]'列表扩展,以防止数组元素的分词(可能不是你的情况的问题,但这样做一般的事情以正确的方式)。 – 2014-08-31 23:48:54

+0

那两个非工作选项不起作用?他们在做什么? (第二个看起来会创建一个空列表,因为'[[''test不返回任何内容(仅返回代码)。你几乎肯定希望在'if'块中进行该测试,然后追加' $ item'到列表中(就像在链接的问题中一样) – 2014-08-31 23:50:14

+0

我同意第二个选项(删除它)第一个给我889111个匹配,而不是4xx个有效匹配$ item是一个完全匹配,我想得到所有更长的匹配(子串) – Xand 2014-08-31 23:55:11

回答

1

Bash脚本不按效益好所有。试试这个:

#!/bin/bash 

# e. g.: ripencc|RU|ipv6|2001:640::|32|19991115|allocated -> ^2001:640: 
awk -v FS='|' \ 
    '$2 == "RU" && $3 == "ipv6" { sub(/::/, ":", $4); print "^" $4 }' \ 
    <(curl -4 ftp://ftp.ripe.net/ripe/stats/delegated-ripencc-latest) \ 
|\ 
# grep e. g. '^2001:640:' in '2001:640:8000::/33' 
grep --basic-regexp --file - \ 
    <(curl -4 http://www.msk-ix.ru/download/lg/msk_ipv6_pfx.txt.gz | gunzip) 
+0

感谢德米特里同志,你最后一次编辑指明了它,并且它比循环更快地执行任何操作,除去来自msk_ipv6_pfx.txt的重复记录?例如2a02:bc8 ::/32和2a02:bc8:fffe ::/48。这两条路由都会转到IX,但更高的前缀就足够了(2a02:bc8 ::/32被委托)再次感谢您 – Xand 2014-09-01 00:31:46

+0

@Xand不客气。:-)至于删除' msk_ipv6_pfx.txt',这看起来不够简单,可以成为一个单独的问题,实际上在这里,在SO上。但是,当然,这是可能的。例如:'$ tac msk_ipv6_pfx.txt | awk -F'::'-v P ='^ $''!/^[#] /&& $ 0!=“”&& $ 1!〜P {P =“^”$ 1;打印}''。这不是一个最佳的方式,但它可以在不反转文件的情况下完成。你需要评论吗? – 2014-09-01 01:26:46

+0

我确实看到线条数量减少了,但上面提到的两个前缀仍然存在(无论如何都需要暂停)。但我真的很欣赏重定向的提示,以便在curl和gunzip后用msk-ix文件提供grep。否则,我想必须将其定义为一个单独的变量。谢谢 – Xand 2014-09-01 02:01:46