Я хочу найти частично совпадающие префиксы ipv6 в двух массивах. Например, 2001:db8:
из одного массива будет соответствовать 2001:db8:1::/48
и 2001: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 секунд). Я нашел этот полезный ответ, который работает намного быстрее, но я не могу заставить его работать так же, как и выше. И я не думаю, что мне нужна конструкция «если», как в примере, потому что она сделает одно и то же дважды. Моя нерабочая версия:
msk=" ${msk_ix_routes[*]} "; # add framing blanks
for item in ${ru_routes[@]}; do
routes+=( egrep -o "$item[\S]*/g" <<< $msk );
done
Я предполагаю, что здесь есть проблемы с цитированием и экранированием, но я не могу это решить. Помогите пожалуйста) Жду предложений.
Кстати, я использовал "comm" в первой версии, которая работает еще быстрее, но затем она делает только точное совпадение, поэтому я начал играть с циклами:
routes=( $(comm -12 <(printf '%s\n' "${ru_routes[@]}" | LC_ALL=C sort) <(printf '%s\n' "${msk_ix_routes[@]}" | LC_ALL=C sort)) );
[@]
, чтобы предотвратить разделение слов элементов массива (вероятно, это не проблема в вашем случае, но правильный способ делать что-то в целом). - person Etan Reisner   schedule 01.09.2014[[
не возвращает никакого содержимого (только код возврата). Вы почти наверняка хотите, чтобы этот тест находился в блокеif
, а затем добавлял$item
к списку (например, в связанном вопросе). - person Etan Reisner   schedule 01.09.2014