首页 > 解决方案 > 使用 powershell 对文本文件中的日志数据进行排序

问题描述

我有一个看起来像这样的日志文件

2019-11-12 14:25:11,538 DEBUG Calculated Value: 0.04

我的愿望是在最后提取值,如果超过一定数量,则发出警报(警报代码已完成)

到目前为止我已经写了这个

$array = @(Get-Content C:\CR1\AllTransFilter.log) 
foreach ($line in $array) {
    $TransDate = $array.Substring(0,10)
    $TransTime = $array.Substring(11,5)
    $CalcValue = $array.Substring(48)
}

现在 $CalcValue 给了我一个值列表,尽管尝试将 $CalcValue 变量转换为双精度,但我得到了错误(我已经添加了 .ToDouble 和 [Double] 并且每次都会出错

所以我的问题是这样的

  1. 这是解决这个问题的正确方法吗?我尝试使用自定义标题转换为 CSV,但没有走远。
  2. 有人可以向我指出一些阅读材料(noobish?)的方向,以操纵数组来实现我需要的东西吗?
  3. 获得计算值并计算其是否高于设定值的最佳方法是什么。

任何帮助是极大的赞赏

编辑

所以使用李的代码

$InStuff = C:\Work\CR1\AllTransFilter.log
$Null = $InStuff -match '^(?<DateTime>.+),.+Calculated Value: (?<CalcValue>.+)$'
$LogLineData = [PSCustomObject]@{
    DateTime = [datetime]$Matches.DateTime
    CalcValue = [float]$Matches.CalcValue
    }

$LogLineData | Out-Host
'=' * 30
$LogLineData.DateTime | Out-Host
$LogLineData.DateTime.GetType() | Out-Host
'=' * 30
$LogLineData.CalcValue | Out-Host
$LogLineData.CalcValue.GetType() | Out-Host

$LogLineData

$logLineData 是否应该检索所有行?因为它只检索一个

对不起,我正在慢慢地了解它。

#

该文件是一个 .log 文件,包含以下几行,一个小样本低于文件大小范围从 100k 到 1mb

2019-11-12 07:58:34,684 DEBUG Calculated Value: 6.41
2019-11-12 08:00:59,823 DEBUG Calculated Value: 24.79
2019-11-12 08:02:44,364 DEBUG Calculated Value: 37.18
2019-11-12 08:06:16,075 DEBUG Calculated Value: 4.95
2019-11-12 08:08:01,202 DEBUG Calculated Value: 32.84
2019-11-12 08:28:31,369 DEBUG Calculated Value: 30.98
2019-11-12 09:29:21,013 DEBUG Calculated Value: 15.27
2019-11-12 09:31:41,489 DEBUG Calculated Value: 6.01
2019-11-12 09:58:21,990 DEBUG Calculated Value: 8.32
2019-11-12 12:13:49,691 DEBUG Calculated Value: 7.63
2019-11-12 15:03:53,459 DEBUG Calculated Value: 6.83
2019-11-12 18:48:07,583 DEBUG Calculated Value: 7.62
2019-11-12 20:23:49,272 DEBUG Calculated Value: 173.53
2019-11-13 06:49:22,654 DEBUG Calculated Value: 3.09
2019-11-13 06:50:45,921 DEBUG Calculated Value: 8.1
$InStuff = 'C:\Test\AllTransFilter.log'
foreach ($Line in $InStuff){
$line = $InStuff -match '^(?<DateTime>.+),.+Calculated Value: (?<CalcValue>.+)$'

$LogLineData = [PSCustomObject]@{
    DateTime = [datetime]$Matches.DateTime
    CalcValue = [float]$Matches.CalcValue
}   
}
$LogLineData | Out-Host
'=' * 30
$LogLineData.DateTime | Out-Host
$LogLineData.DateTime.GetType() | Out-Host
'=' * 30
$LogLineData.CalcValue | Out-Host
$LogLineData.CalcValue.GetType() | Out-Host

是我到目前为止所拥有的,谢谢Lee,它给了我以下输出

DateTime            CalcValue
--------            ---------
12/11/2019 14:25:11      0.04


==============================

12 November 2019 14:25:11



IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     DateTime                                 System.ValueType


==============================
0.04

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     Single                                   System.ValueType

您能否让我知道如何正确执行 foreach,我刚刚注意到日志文件中实际不存在输出,我在上面的已清理输出中粘贴了相同的日期,并且在 14:25 处没有计算值,所以现在我真的很困惑。

标签: arrayspowershellsortingobjectdata-manipulation

解决方案


虽然Benjamin Hubbard已经指出了您的故障 [ grin ] 的最可能来源,但您使用的方法 - .SubString()- 相当慢。如果您对日志中的许多行执行此操作,那么切换到某种正则表达式进行解析可能是值得的。以下代码使用命名捕获组和自动变量$Matches来构建 PSCustomObject。它还创建一个[datetime]对象而不是日期字符串和时间字符串


请注意,这仅涵盖将值放入适当的对象中。它不包括您的阈值测试。[咧嘴笑]


代码的作用...


  • 当您确信文本文件正常工作时,假装读取文本文件,请将该部分 [在foreach]之前的所有内容替换Get-Content为加载真实文件而不是测试数据的调用。
  • 遍历生成的文本行集合
  • 在线运行正则表达式匹配以生成命名的捕获组,
    这些捕获组自动存储在自动变量$Matches中。
  • [PSCustomObject]如果您想在不同的道具中使用日期和时间,则使用所需的属性构建一个
    ,您将需要修改正则表达式或独立计算这两个项目。
  • 将日期时间字符串转换为日期时间对象
  • 将其分配给适当的属性 [ grin ]
  • 对计算的值数据做同样的事情
  • 将新的自定义对象发送到$Results集合
  • 在屏幕上显示该集合

此时,您可以根据需要优雅地处理这些值。

这是代码...

# fake reading in a text file
#    in real life, use Get-Content
$InStuff = @'
2019-11-12 07:58:34,684 DEBUG Calculated Value: 6.41
2019-11-12 08:00:59,823 DEBUG Calculated Value: 24.79
2019-11-12 08:02:44,364 DEBUG Calculated Value: 37.18
2019-11-12 08:06:16,075 DEBUG Calculated Value: 4.95
2019-11-12 08:08:01,202 DEBUG Calculated Value: 32.84
2019-11-12 08:28:31,369 DEBUG Calculated Value: 30.98
2019-11-12 09:29:21,013 DEBUG Calculated Value: 15.27
2019-11-12 09:31:41,489 DEBUG Calculated Value: 6.01
2019-11-12 09:58:21,990 DEBUG Calculated Value: 8.32
2019-11-12 12:13:49,691 DEBUG Calculated Value: 7.63
2019-11-12 15:03:53,459 DEBUG Calculated Value: 6.83
2019-11-12 18:48:07,583 DEBUG Calculated Value: 7.62
2019-11-12 20:23:49,272 DEBUG Calculated Value: 173.53
2019-11-13 06:49:22,654 DEBUG Calculated Value: 3.09
2019-11-13 06:50:45,921 DEBUG Calculated Value: 8.1
'@ -split [System.Environment]::NewLine

$Results = foreach ($IS_Item in $InStuff)
    {
    $Null = $IS_Item -match '^(?<DateTime>.+),.+Calculated Value: (?<CalcValue>.+)$'

    [PSCustomObject]@{
        DateTime = [datetime]$Matches.DateTime
        CalcValue = [float]$Matches.CalcValue
        }
    }

$Results

输出 ...

DateTime               CalcValue
--------               ---------
2019-11-12 7:58:34 AM       6.41
2019-11-12 8:00:59 AM      24.79
2019-11-12 8:02:44 AM      37.18
2019-11-12 8:06:16 AM       4.95
2019-11-12 8:08:01 AM      32.84
2019-11-12 8:28:31 AM      30.98
2019-11-12 9:29:21 AM      15.27
2019-11-12 9:31:41 AM       6.01
2019-11-12 9:58:21 AM       8.32
2019-11-12 12:13:49 PM      7.63
2019-11-12 3:03:53 PM       6.83
2019-11-12 6:48:07 PM       7.62
2019-11-12 8:23:49 PM     173.53
2019-11-13 6:49:22 AM       3.09
2019-11-13 6:50:45 AM        8.1

推荐阅读