Sed: Искать IP-адрес в диапазоне?

printf "">MergeFile
cat A.txt B.txt | 
while IFS= read -r line; do 
  if [ ! -z "$line" ]; then
    if ! grep -Fxqe "$line" MergFile; then
      echo "$line">>MergeFile;
    fi
  fi
done

Пояснение

Создайте новый файл слияния с помощью
printf ""> MergeFile # или, необязательно: touch MergeFile

Соедините два файла с циклом while:
cat A. txt B.txt |

Прочитать каждую строку:
while IFS = read -r line; do

Обрабатывать пустые строки:
if [! -z "$ строка"]; then
* если вы хотите сохранить первую пустую строку, добавьте ее обратно в предложение else

Пустые результаты означают, что она впервые попадает в MergeFile (т.е. уникальна):
if! grep -Fxqe "$ line" MergFile; затем

Добавьте его в MergeFile:
echo "$ line" >> MergeFile;

1
22.03.2016, 19:16
2 ответа

Числовые диапазоны плохо подходят для регулярных выражений, так как они требуют, чтобы такие выражения, как

gsed '/192\.200\.1\([6-8][0-9]\|9[01]\)\./s/$/ --- APIv2 SYSTEMS/'

, соответствовали между 160 и 191, поэтому в идеале вам нужно напишите код, который мог бы генерировать выражение, так как вероятность человеческой ошибки при написании или изменении его вручную будет чрезвычайно высока.Лучшим решением может быть то, что понимает IP-адреса и поддерживает нотацию CIDR, например модуль Perl NetAddr :: IP , а затем проанализировать IP-адреса и проверить, находятся ли они -> в пределах некоторого диапазона, проанализированного из другого места.

2
27.01.2020, 23:26

Краткий (не-SED) ответ

Извините, но это лучшее, что я смог сделать в виде одной строчки. Очевидно, что это не SED.

perl -MNetAddr::IP -i.bak -nle '$re=NetAddr::IP->new("85.159.56.0/24")->re(); if(/$re/){ print $_ . " --- APIv2 SYSTEMS"}else{print}' yourfile.txt

Что это делает

Это возьмет подсеть "85.159.56.0/24" и превратит ее в регулярное выражение, затем проверит каждую строку на это выражение, если есть совпадение, то добавит " --- APIv2 SYSTEMS" в конец строки.

  • "-Mmodule" загружает модуль перед выполнением кода.
  • "-i.bak" означает, что он изменит файл (yourfile.txt) на месте и сделает резервную копию как yourfile.txt.bak
  • "-n" заставляет Perl зациклиться вокруг вашей программы, что заставляет его перебирать аргументы имени файла, примерно как sed -n или awk
  • "-s" позволяет вам задавать аргументы вне программы
  • и " -- -variable=X" - это то, как мы это задаем.
  • "-l" - потому что я ленивый, он очищает строку ввода и добавляет возврат каретки к любому выводу
  • наконец, "-e 'print "I'm a one-liner"" - это бит, который содержит код

Просто REGEX

Если вам нужен просто regex (для использования в grep или sed/awk и т.д.):

perl -MNetAddr::IP -lse 'print NetAddr::IP->new($range)->re()' -- -range=85.159.56.0/24

Что выводит следующее, если вам интересно:

(?:(?<![0-9])85\.159\.(?:56)\.(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])(?![0-9]))

Предварительное требование

Стоит отметить, что вам может понадобиться установить модуль NetAddr: :IP модуль из cpan (я использую cpanm, потому что у меня недостаточно памяти, но синтаксис тот же:

sudo cpanm install NetAddr::IP

Заключительный комментарий

SED и AWK - фантастические инструменты, у меня действительно есть пара книг по ним и я стараюсь использовать их, когда это необходимо, однако Perl обычно прикрывает вашу спину своим набором модулей и всей этой штукой с одним строкой. Я уверен, что в Python тоже есть такие инструменты, но я фанат Perl. Могу также порекомендовать http://explainshell.com, который я часто использую, чтобы выяснить, что кто-то попросил меня запустить. Он принимает команду и различные переключатели/аргументы и просто показывает вам соответствующую часть man-страниц.

1
27.01.2020, 23:26

Теги

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