当前,我在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语法。
答案 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命令,其中:
更具可读性(因此,必不可少,更加冗长)
涉及的步骤更少
最终提供了更大的灵活性:
sort -t ' ' -n -b
之类的POSIX外壳相比)可以轻松地编织到管道中。也就是说,您为提高功率所付出的代价是性能:
这是命令,在注释中带有大致相应的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安装的一部分获得。 :
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*
运算符)答案 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的输出表示。