使用PowerShell按日期拆分多日期混合的日志文件
需求说明
我有一个包含多日期条目的日志文件,需要将其拆分为多个独立文件,每个文件仅包含对应日期的条目。例如文件命名为1-2-23时,仅包含2023年1月2日的条目;1-3-23仅包含2023年1月3日的条目,以此类推。日志条目以-----------------------作为分隔线,且日志包含数千条条目,需要高效的PowerShell实现方案。
日志文件示例
entry is HOSTFIT 0 inserted group is 0 entry is HOSTFIT 0 code entered chose no 184357 ejected 184400 taken 184404 presented USD 16X20 == NOV 09, 2022 COMPNAME == 184405 taken 11/09/22 18:43 COMPNAME 12345******6789 SEQ 4201 RANDOMTEXT 320.00 FROM ****882 COMPLETED SUCCESSFULLY AVAIL 32456 A1234567891011 PROCESS ----------------------- inserted group is 1 entry is HOSTFIT 1 ntry is HOSTFIT 1 192153 inserted group is 1 entry is HOSTFIT 1 code entered chose receipt 192221 ejected 192222 aken 192226 presented 240 USD 12X20 192227 taken 11/09/22 19:22 12274267 45678******9101 SEQ 4202 WITH %240.00 FROM COMPLETED SUCCESSFULLY AVAIL 936.77 A1234567891011 US -----------------------
尝试过的代码
代码1
get-content $Log | select-string -SimpleMatch '-----------------------' | set-content "C:\Users\User\Desktop\Projects\Archive\Temp\TestAudit.log"
代码2
Get-ChildItem $Log -recurse | ForEach-Object { Get-Content $_ | ForEach-Object { $fields = $_.split('-----------------------') [pscustomobject]@{ Field7 = $fields[7] Field8 = $fields[8] Field10 = $fields[10] } } } | Export-CSV "C:\Users\User\Desktop\Projects\Archive\Temp\TestAudit.csv" -NoTypeInformation
高效实现方案
# 日志文件路径 $logPath = "C:\path\to\your\logfile.log" # 输出目录,确保目录存在 $outputDir = "C:\Users\User\Desktop\Projects\Archive\SplitLogs" if (-not (Test-Path $outputDir)) { New-Item -ItemType Directory -Path $outputDir | Out-Null } # 一次性读取整个日志文件,按分隔线分割条目并过滤空内容 $entries = (Get-Content $logPath -Raw) -split '-----------------------' | ForEach-Object { $_.Trim() } | Where-Object { $_ -ne '' } # 用哈希表缓存文件流,避免重复打开关闭文件 $fileStreams = @{} foreach ($entry in $entries) { # 匹配日志中的两种日期格式:MM/DD/YY 或 MMM DD, YYYY $dateMatch = [regex]::Match($entry, '(?:(\d{1,2})/(\d{1,2})/(\d{2}))|(?:([A-Z]{3}) (\d{1,2}), (\d{4}))') if ($dateMatch.Success) { # 生成指定格式的文件名 $fileName = if ($dateMatch.Groups[1].Success) { # 处理 MM/DD/YY 格式,转为 M-D-YY "$($dateMatch.Groups[1].Value)-$($dateMatch.Groups[2].Value)-$($dateMatch.Groups[3].Value)" } else { # 处理 MMM DD, YYYY 格式,转为 MM-D-YY $monthMap = @{ 'JAN' = '1'; 'FEB' = '2'; 'MAR' = '3'; 'APR' = '4'; 'MAY' = '5'; 'JUN' = '6' 'JUL' = '7'; 'AUG' = '8'; 'SEP' = '9'; 'OCT' = '10'; 'NOV' = '11'; 'DEC' = '12' } $month = $monthMap[$dateMatch.Groups[4].Value] "$month-$($dateMatch.Groups[5].Value)-$($dateMatch.Groups[6].Value.Substring(2))" } $filePath = Join-Path $outputDir $fileName # 缓存文件流,减少IO操作 if (-not $fileStreams.ContainsKey($filePath)) { $fileStreams[$filePath] = [System.IO.StreamWriter]::new($filePath, $true) } # 写入条目及分隔线(可根据需求移除分隔线) $fileStreams[$filePath].WriteLine($entry) $fileStreams[$filePath].WriteLine('-----------------------') } } # 关闭并释放所有文件流 foreach ($stream in $fileStreams.Values) { $stream.Close() $stream.Dispose() }
方案优势
- 低IO开销:用
-Raw一次性读取整个文件,配合文件流缓存,避免频繁打开/关闭文件,适合处理数千条日志的场景。 - 日期兼容性:自动识别日志中的两种日期格式,并转换为指定的文件名格式。
- 空内容过滤:分割后自动过滤空白条目,避免生成无效空文件。
内容的提问来源于stack exchange,提问作者BCon995
相关产品推荐
相关产品推荐

