командная строка grep в Windows PowerShell для подсчета IP-адресов - PullRequest
0 голосов
/ 06 марта 2019

В настоящее время я использую эту команду в Linux:

grep Ban /var/log/fail2ban.log | grep -v 'Restore Ban' | sed 's/\s\s*/ /g' | cut -d" " -f8 | sort | uniq -c | sort -t ' ' -n -b

Файл журнала выглядит так:

2019-03-04 07:14:45,778 fail2ban.filter         [19052]: INFO    [sshd] Found 2*8.1*7.1*9.2*9
2019-03-04 07:14:46,412 fail2ban.actions        [19052]: NOTICE  [sshd] Ban 2*8.1*7.1*9.2*9
2019-03-04 07:15:04,708 fail2ban.actions        [19052]: NOTICE  [sshd] Unban 1*9.2*.2*4.1*6
...

Вывод выглядит так:

8  1*2.2*6.1*1.1*5
12  3*.1*.*4.*6
18 1*5.2*8.2*5.4
19 1*2.2*6.1*1.1*4
72 3*.1*6.2*.9*

Я уже пробовал это с Get-Content, но я не понимаю весь синтаксис PowerShell.

Ответы [ 2 ]

1 голос
/ 06 марта 2019

Ваша команда Linux объединяет множество функций в одном конвейере.
Несмотря на отсутствие усилий для самостоятельного решения проблемы, создание эквивалентной команды PowerShell - интересное упражнение по контрасту Unix-утилиты с решением PowerShell :

Чтобы установить сцену, позвольте мне объяснить, что делает ваша команда:

  • grep Ban /var/log/fail2ban.log с учетом регистра находит строки, содержащие слово Ban в файле /var/log/fail2ban.log, и пропускает только те, которые включены.

  • grep -v 'Restore Ban' далее (с учетом регистра) отфильтровывает (-v) строки, содержащие фразу «Запрет на восстановление».

  • sed 's/\s\s*/ /g' заменяет все (g) серии из 1 или более пробелов. (\s; в современном диалекте регулярных выражений вы используете \s+) с одним пробелом ...

  • ... который затем позволяет cut -d" " -f8 надежно извлекать восьмое поле из каждой строки из результирующего списка, разделенного пробелами (например, 2*8.1*7.1*9.2*9).

  • sort затем лексически сортирует результирующие строки и uniq -c отсеивает дубликаты, добавляя каждую уникальную строку с счетчиком дубликатов (-c) с 1 с указанием уникальной строки.

  • Наконец, sort -t ' ' -n -b сортирует результирующие строки численно по количеству дубликатов.

Вкратце: ваша команда фильтрует файл журнала с помощью сопоставления с регулярным выражением, извлекает 8-е поле из каждой строки, удаляет дубликаты и печатает уникальные поля с префиксом по количеству дубликатов, отсортированные по количеству дубликатов в порядке возрастания.


Ниже приведена почти эквивалентная команда PowerShell , которая:

  • более читабельно (и, следовательно, по необходимости, более многословно)

  • включает меньше шагов

  • в конечном итоге обеспечивает гораздо большую гибкость благодаря:

    • отправка объектов по конвейеру, а не просто text , который часто нужно (пере) анализировать - именно эта функция составляет эволюционный квантовый скачок PowerShell по сравнению с традиционными оболочками.
    • намного превосходящие языковые возможности (по сравнению с POSIX-подобными оболочками, такими как bash), которые можно легко вплетать в конвейер.

При этом цена, которую вы платите за увеличение мощности, составляет производительность :

  • Команды прямого сопоставления работают намного лучше, используя утилиты Unix, хотя обычно более высокий уровень абстракции и гибкость, предоставляемые командлетами PowerShell, могут восполнить это.

Вот команда с примерно соответствующими вызовами Unix-утилит в комментариях:

Select-String -CaseSensitive '(?<!Restore )Ban' /var/log/fail2ban.log | #grep,grep -v
  ForEach-Object { (-split $_.Line)[7] } | # sed, cut -f8
    Group-Object | # uniq -c 
      Select-Object Count, Name | # construction of output *objects*
        Sort-Object Count, Name # sort, sort -n

Команда выводит объекты со свойством .Count (повторяющееся число) и .Name (восьмое поле из файла журнала), которое:

  • допускает надежную дополнительную обработку (синтаксический анализ текстового вывода не требуется).
  • дружественно рендерится на консоль (см. Ниже).

Пример вывода:

Count Name
----- ----
    8 1*2.2*6.1*1.1*5
   12 3*.1*.*4.*6
   18 1*5.2*8.2*5.4
   19 1*2.2*6.1*1.1*4
   72 3*.1*6.2*.9*

Для объяснения команды обратитесь к следующим разделам справки , которые также доступны локально, как часть установки PowerShell, с помощью командлета Get-Help

0 голосов
/ 06 марта 2019
((Get-Content "fail2ban.log") -cmatch "(?<!Restore )Ban" | Select-String -Pattern "[0-9.*]+$" -AllMatches).matches.value | Group-Object | foreach {"$($_.count) $($_.name)"}

Get-Content захватывает каждую строку файла fail2ban.log. Оператор -cmatch выполняет регистрозависимое совпадение с учетом регистра. Шаблон регулярного выражения ищет строку Ban с отрицательным взглядом позади строки Restore. Select-String ищет шаблон регулярного выражения в конце каждой строки, в которой есть символы в наборе (0123456789. *). Свойство match.value выводит только совпадающие строки из регулярного выражения. Group-Object группирует каждое идентично совпадающее значение как свойство Name и добавляет свойство count. Так как OP собирал счетчик, я решил использовать Group-Object, чтобы легко получить это. Foreach просто выполняет форматирование в соответствии с выходным представлением OP.

...