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

问题描述 投票:0回答:2

目前我在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语法。

linux powershell grep command
2个回答
1
投票

您的Linux命令将大量功能打包到单个管道中。 尽管你自己也没有努力解决这个问题,但构建一个等效的PowerShell命令是一个有趣的练习,它将Unix实用程序解决方案与PowerShell解决方案进行对比:

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

  • grep Ban /var/log/fail2ban.log区分大小写,在文件Ban中找到包含单词/var/log/fail2ban.log的行,并仅传递那些。
  • grep -v 'Restore Ban'进一步(区分大小写)过滤掉(-v)包含短语'Restore Ban'的行。
  • sed 's/\s\s*/ /g'取代所有(g)一个或多个空格字符的运行。 (\s;在现代的正则表达方言中,你使用\s+)只有一个空间......
  • ...然后允许cut -d" " -f8从得到的空格分隔列表(例如,2*8.1*7.1*9.2*9)中可靠地从每一行中提取第8个字段。
  • 然后sort对词汇进行词汇排序,并且uniq -c除去重复数据,同时在每个唯一行前面加上重复数(-c),1表示一个独特的行。
  • 最后,sort -t ' ' -n -b通过重复计数对数字生成的行进行排序。

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


以下是近似等效的PowerShell命令,其中:

  • 更具可读性(因此,必要性更详细)
  • 涉及更少的步骤
  • 最终提供了更大的灵活性,原因如下: 通过管道发送对象,而不仅仅是必须经常(重新)解析的文本 - 正是这一特性构成了PowerShell从传统shell中演化的巨大飞跃。 远远优越的语言特征(与像bash这样的POSIX类似的外壳)可以很容易地编织成管道。

也就是说,你为增加的功率支付的价格是性能:

  • 尽管PowerShell cmdlet提供的通常更高级别的抽象和灵活性可以弥补这一点,但使用Unix实用程序可以直接比较命令。

这是命令,在注释中大致相应的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属性(日志文件中的第8个字段)输出对象,其中:

  • 允许强大的额外处理(不需要解析文本输出)。
  • 以友好的方式呈现给控制台(见下文)。

示例输出:

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*

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


0
投票
((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. *)。 matches.value属性仅输出正则表达式中匹配的字符串。 Group-Object将每个相同匹配的值组作为属性Name并添加count属性。由于OP是捕获计数,我决定使用Group-Object轻松获得它。 foreach只是进行格式化以匹配OP的输出表示。

© www.soinside.com 2019 - 2024. All rights reserved.