目前我在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命令是一个有趣的练习,它将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命令,其中:
bash
这样的POSIX类似的外壳)可以很容易地编织成管道。也就是说,你为增加的功率支付的价格是性能:
这是命令,在注释中大致相应的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安装的一部分在本地获得:
Select-String
about_Regular_ExpressionsForEach-Object
about_Split(-split
运营商)Group-Object
Select-Object
要了解有关重命名属性或创建计算属性的信息,请参阅this answer。Sort-Object
((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的输出表示。