【发布时间】:2017-01-15 16:13:25
【问题描述】:
背景
我一直在查看 Stack 上的几篇帖子,只能找到“如何将单行数据添加到 CSV 文件”的答案(尤其是 this one)。虽然它们很好,但它们仅指从内存中添加单个条目的特定情况。假设我有 100,000 行要添加到 CSV 文件中,那么如果我将每一行都写入文件,查询速度将会慢几个数量级。我想将所有内容保存在内存中会更快,并且一旦我构建了一个包含我要添加的所有数据的变量,然后才将其写入文件。
现状
我有从客户那里收到的包含大约一百万行的日志文件。其中一些行以日期时间和服务器使用的内存量开头。为了更好地了解内存使用情况,我想使用此信息绘制一段时间内的内存使用情况。 (注意:是的,最好的解决方案是要求开发人员添加此信息,因为我们需要此信息很常见,但由于我们还没有,我需要使用我得到的信息)
我能够读取日志文件,提取内容,创建两个变量 $timeStamp 和 $memoryUsage 来查找所有相关条目。当我尝试将其添加到自定义PSObject 时出现问题。似乎使用 $csvObject += $newRow only adds a pointer to the $newRow variable 而不是实际的行本身。这是我目前得到的代码:
$header1 = "Time Stamp"
$header2 = "Memory Usage"
$csvHeaders = @"
$header1;$header2
"@
# The following two lines are a workaround to make sure that the $csvObject becomes a PSObject that matches the output I'm trying to achieve.
$csvHeaders | Out-File -FilePath $csvFullPath
$csvObject = Import-Csv -Path $csvFullPath -Delimiter ";"
foreach ($TraceFile in $traceFilesToLookAt) {
$curTraceFile = Get-Content $TraceFile.FullName
Write-Host "Starting on file: $($TraceFile.Name)`n"
foreach ($line in $curTraceFile) {
try {
if (($line.Substring(4,1) -eq '-') -and ($line.Substring(7,1) -eq '-')) {
$TimeStamp = $line.Split("|",4)[0]
$memoryUsage = $($line.Split("|",4)[2]).Replace(",","")
$newRow = New-Object PSObject -Property @{
$header1 = $TimeStamp;
$header2 = $memoryUsage
}
$reorderedRow = $newRow | Select-Object -Property $header1,$header2
$reorderedRow | Export-Csv -Path $csvFullPath -Append -Delimiter ";"
}
} catch {
Out-Null
}
这很好用,因为它每次在 CSV 文件中找到一行时都会附加该行。问题是效率不高。
最终目标
理想情况下,我想通过以下方式解决它:
$newRow = New-Object PSObject -Property @{
$header1 = $TimeStamp;
$header2 = $memoryUsage
}
$rowsToAddToCSV += $newRow
然后在最后一步做:
$rowsToAddToCSV | Export-Csv -Path $csvFullPath -Append -Delimiter ";"
我无法为此创建任何形式的解决方法。除其他外,PowerShell 告诉我 op_Addition 不是对象的一部分,我尝试导出的对象(行的集合)与 CSV 文件等不匹配。
【问题讨论】:
标签: powershell csv