Windows PowerShell中的grep命令行来计算IP地址

时间:2019-03-06 14:59:16

标签: linux powershell grep command

当前,我在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 个答案:

答案 0 :(得分:1)

您的Linux命令将许多功能打包到一个管道中。
尽管您自己仍不愿意解决问题,但是构造等效的PowerShell命令却是一个有趣的练习 具有PowerShell解决方案的Unix实用程序解决方案

要设置场景,让我解释一下您的命令的作用:

  • grep Ban /var/log/fail2ban.log区分大小写地查找文件Ban中包含单词/var/log/fail2ban.log的行,并仅将其传递。

  • grep -v 'Restore Ban'进一步(区分大小写)过滤出(-v)行,其中包含短语“ Restore Ban”。

  • sed 's/\s\s*/ /g'替换1个或多个空格字符的所有(g)运行。 (\s;在现代正则表达式中,您应该使用\s+)和单个空格 ...

  • ...然后允许cut -d" " -f8从所得的以空格分隔的列表(例如2*8.1*7.1*9.2*9)的每一行中可靠地提取第8个字段。

  • sort然后对结果行进行词法排序,uniq -c清除重复项,同时在每个唯一行之前添加重复项的 count ({{1} }),其中-c表示唯一行。

  • 最后,1通过重复计数对所得行进行数字排序。

简而言之:您的命令通过正则表达式匹配过滤日志文件,从每行中提取第8个字段,消除重复项,并打印带有重复计数前缀的唯一字段,并按重复计数按升序排序。


下面是一个几乎等效的PowerShell命令,其中:

  • 更具可读性(因此,必不可少,更加冗长)

  • 涉及的步骤更少

  • 由于以下原因,
  • 最终提供了更大的灵活性:

      通过管道
    • 发送对象,而不仅仅是经常必须(重新)解析的 text -正是此功能构成了PowerShell从传统shell到进化的飞跃。 / li>
    • 非常优越的语言功能(与sort -t ' ' -n -b之类的POSIX外壳相比)可以轻松地编织到管道中。

也就是说,您为提高功率所付出的代价是性能

  • 使用Unix实用程序直接可比较的命令执行效果要好得多,尽管PowerShell cmdlet通常提供更高的抽象水平和灵活性可以弥补这一点。

这是命令,在注释中带有大致相应的Unix-utility调用:

bash

该命令输出具有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属性(日志文件的第8个字段)的对象

  • 允许进行强大的附加处理(无需解析文本输出)。
  • 以友好的方式呈现到控制台(见下文)。

示例输出:

.Name

有关命令的解释,请查阅以下帮助主题,这些主题也可以通过Get-Help cmdlet在本地作为PowerShell安装的一部分获得。 :

答案 1 :(得分:0)

((Get-Content "fail2ban.log") -cmatch "(?<!Restore )Ban" | Select-String -Pattern "[0-9.*]+$" -AllMatches).matches.value | Group-Object | foreach {"$($_.count) $($_.name)"}

此处的获取内容正在获取fail2ban.log文件的每一行。 -cmatch运算符正在执行区分大小写的正则表达式匹配。 regex模式查找字符串Ban,其后跟字符串Restore。 Select-String在每行的末尾查找正则表达式模式,该行中的字符集中为(0123456789. *)。 matchs.value属性仅从正则表达式输出匹配的字符串。组对象将每个相同匹配的值分组为属性名称,并添加一个计数属性。由于OP捕获计数,因此我决定使用Group-Object轻松获得该计数。 foreach只是在进行格式化以匹配OP的输出表示。