Вы можете использовать grepcidr , чтобы проверить, входит ли IP-адрес в список сетей CIDR.
#! /bin/bash
NETWORKS="108.161.176.0/20 94.46.144.0/20 146.88.128.0/20 198.232.124.0/22
23.111.8.0/22 217.22.28.0/22 64.125.76.64/27 64.125.76.96/27
64.125.78.96/27 64.125.78.192/27 64.125.78.224/27 64.125.102.32/27
64.125.102.64/27 64.125.102.96/27 94.31.27.64/27 94.31.33.128/27
94.31.33.160/27 94.31.33.192/27 94.31.56.160/27 177.54.148.0/24
185.18.207.65/26 50.31.249.224/27 50.31.251.32/28 119.81.42.192/27
119.81.104.96/28 119.81.67.8/29 119.81.0.104/30 119.81.1.144/30
27.50.77.226/32 27.50.79.130/32 119.81.131.130/32 119.81.131.131/32
216.12.211.59/32 216.12.211.60/32 37.58.110.67/32 37.58.110.68/32
158.85.206.228/32 158.85.206.231/32 174.36.204.195/32
174.36.204.196/32"
for IP in 108.161.184.123 108.161.176.123 192.168.0.1 172.16.21.99; do
grepcidr "$NETWORKS" <(echo "$IP") >/dev/null && \
echo "$IP is in MAXCDN range" || \
echo "$IP is not in MAXCDN range"
done
ПРИМЕЧАНИЕ: grepcidr
ожидает, что совпадающие IP-адреса будут в файле, а не просто аргументом в командной строке. Вот почему мне пришлось использовать выше.
Вывод:
108.161.184.123 is in MAXCDN range
108.161.176.123 is in MAXCDN range
192.168.0.1 is not in MAXCDN range
172.16.21.99 is not in MAXCDN range
grepcidr
доступен предварительно упакованным для нескольких дистрибутивов, включая Debian:
Package: grepcidr
Version: 2.0-1
Description-en: Filter IP addresses matching IPv4 CIDR/network specification
grepcidr can be used to filter a list of IP addresses against one or
more Classless Inter-Domain Routing (CIDR) specifications, or
arbitrary networks specified by an address range. As with grep, there
are options to invert matching and load patterns from a file.
grepcidr is capable of comparing thousands or even millions of IPs
to networks with little memory usage and in reasonable computation
time.
.
grepcidr has endless uses in network software, including: mail
filtering and processing, network security, log analysis, and many
custom applications.
Homepage: http://www.pc-tools.net/unix/grepcidr/
В противном случае исходный код доступен по ссылке выше.
Другой альтернативой является написание сценария perl
или python
с использованием одной из многих библиотек / модулей для управления и проверки адресов IPv4 на этих языках.
Например, модуль perl
Data :: Validate :: IP
имеет функцию is_innet_ipv4 ($ ip, $ network)
; Net :: CIDR :: Lite
имеет очень похожий метод $ cidr-> find ($ ip);
; и Net :: IPv4Addr
имеет функцию ipv4_in_network ()
.
python
имеет сопоставимые библиотеки, в том числе ipy
, ipaddr
и ipcalc
, среди прочих.
С sed
, echo
иtr
:
$ se () { echo -n "$1 "; sed -n 's/\s*r('"$2"').*|r| =\s\+//p' DEMLIR-GEO_OPT-1-distance-1.coordLog | tr '\n' ' '; echo; }
$ se 0 1,5; se 1 2,5; se 2 2,8
0 1.869679 1.869821 1.869881
1 1.530989 1.531483 1.531900
2 1.849134 1.849626 1.849678
# using a for-loop
cnt=0; for i in 1,5 2,5 2,8; do se $((cnt++)) $i; done
Чтобы записать вывод в файл, вы можете использовать
{ se 0 1,5; se 1 2,5; se 2 2,8; } > DEMLIR_task.txt
Если это был неправильный порядок, вы можете использовать этот фрагмент, используя sed
, paste
и printf
:
$ se () { sed -n 's/\s*r('"$1"').*|r| =\s\+//p' DEMLIR-GEO_OPT-1-distance-1.coordLog; }
$ paste -d' ' <(printf '%s\n' 0 1 2) <(se 1,5) <(se 2,5) <(se 2,8)
0 1.869679 1.530989 1.849134
1 1.869821 1.531483 1.849626
2 1.869881 1.531900 1.849678
# using a for-loop and temp files, first column starts with 1 instead of 0
rm -f tmp.*; cnt=0; for i in 1,5 2,5 2,8; do se $i > tmp.$((cnt++)); done; paste -d ' ' tmp.* | cat -n
Вы получаете сообщение об ошибке dist1: unbound variable
, поскольку вы установили параметр оболочки nounset
. Затем вы используете переменную dist1
до ее установки.
/REQUESTED STRUCTURE DATA/ { ++n; m = 0 }
$6 == "|r|" { r[n,++m] = $NF }
END {
for (j = 1; j <= m; ++j) {
$0 = j - 1
for (i = 1; i <= n; ++i)
$(i + 1) = r[i,j]
print
}
}
(перенаправить вывод, например. awk... >DEMLIR_task.txt
для сохранения в новый файл)
Данные поступают в виде разделов, каждый раздел начинается со строки REQUESTED STRUCTURE DATA
и содержит ряд записей. Записи можно найти, ища строку |r|
в 6-м поле.
Приведенная выше программа awk
выводит числа, собранные из последнего поля каждой записи в разделе в столбцах, каждой строке предшествует счетчик. Предполагается, что может быть любое количество записей для каждой секции(m
в коде )и что может быть любое количество секций во входных данных(n
в коде ).
Тестирование:
$ awk -f script.awk file
0 1.869679 1.869821 1.869881
1 1.530989 1.531483 1.531900
2 1.849134 1.849626 1.849678
Возможное решение только в awk
. Я создалprg.awk
:
BEGIN { j=0; }
{
if ( $1 == "r(1,5)" )
{
dist1=$8;
}
if ( $1 == "r(2,5)" )
{
dist2=$8;
}
if ( $1 == "r(2,8)")
{
dist3=$8;
print j": "dist1" "dist2" "dist3;
++j;
}
}
Содержаниеfile.txt
:
yurijs-MacBook-Pro:bash yurij$ cat./file.txt
REQUESTED STRUCTURE DATA
Distance vector r(i,j) between the atom i and j in ANGSTROM
r(1,5) = 0.944776 0.190651 1.602108 |r| = 1.869679
r(2,5) = -0.693580 -0.927860 -1.000974 |r| = 1.530989
r(2,8) = 1.618580 0.570765 -0.688275 |r| = 1.849134
REQUESTED STRUCTURE DATA
Distance vector r(i,j) between the atom i and j in ANGSTROM
r(1,5) = 0.945905 0.187745 1.601950 |r| = 1.869821
r(2,5) = -0.692409 -0.928976 -1.001505 |r| = 1.531483
r(2,8) = 1.618487 0.572023 -0.688769 |r| = 1.849626
REQUESTED STRUCTURE DATA
Distance vector r(i,j) between the atom i and j in ANGSTROM
r(1,5) = 0.946708 0.186226 1.601724 |r| = 1.869881
r(2,5) = -0.691970 -0.929421 -1.002033 |r| = 1.531900
r(2,8) = 1.618395 0.572685 -0.688576 |r| = 1.849678
Запустить программу:
yurijs-MacBook-Pro:bash yurij$ awk -f prg.awk./file.txt
0: 1.869679 1.530989 1.849134
1: 1.869821 1.531483 1.849626
2: 1.869881 1.531900 1.849678