Если строка содержит шаблон, вывести переменную в столбец

Вы можете использовать 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 , среди прочих.

1
01.05.2019, 22:03
3 ответа

С 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
0
27.01.2020, 23:30

Вы получаете сообщение об ошибке 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
0
27.01.2020, 23:30

Возможное решение только в 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
2
27.01.2020, 23:30

Теги

Похожие вопросы