首页 > 解决方案 > Powershell在txt文件中输出记录列表

问题描述

在 powershell 中运行以下命令

$files = Get-ChildItem -path "C:\temp" -Recurse -Include "*.csv" 

ForEach($BusinessFile in $BusinessFiles)
{
$bfiles = get-content $BusinessFile.fullname | Measure-Object -line
$bRowsinFile = $bfiles.lines -1

write-host  "Business File Name: " $BusinessFile.name 
Write-host "Number of Rows: " $bRowsinFile -ForegroundColor Yellow 
} 

$records =@{
"File Name" = $businessFile.Name
"Number of Rows" = $bRowsinFile
}
} 

$listofFiles = @()
$listofFiles += New-Object -TypeName PSObject -Property $records

$listofFiles | Out-File "c:\test\output.txt"
Invoke-Item "c:\test\output.txt"

基于 write-host 命令的 Powershell 工作正常。它给出了每个 CSV 文件名以及每个文件上的行数

输出问题:我只看到 output.txt 文件中的第一个文件名

输出显示:仅第一个文件的文件名和 # 行

目标: output.txt 是否可以列出所有文件名以及相应的行数

谢谢

标签: powershellcalculated-property

解决方案


您的问题是您错误地尝试在循环之后而不是在循环内部$listofFiles += ...构建结果数组( )foreach - 正确缩进源代码,该问题会更加明显。

此外,您可以大大简化解决方案。

$listOfFiles = Get-ChildItem C:\temp -Recurse -Filter *.csv | ForEach-Object {
  [pscustomobject] @{
    'File Name' = $_.Name
    'Number of Rows' = (Get-Content $_.FullName | Measure-Object -Line).Lines - 1
  }
}

在命令中[pscustomobject]手动构建的替代方法是使用计算属性,如TheMadTechnician 的答案所示。也就是说,考虑到在手头的情况下,您需要两个计算属性 - 一个用于计算行数,另一个用于将属性重命名为,增加的冗长可能不值得。ForEach-ObjectSelect-ObjectNameFile Name

警告:正如Compo所指出的,如果您的 CSV 文件有可能包含跨越多行的单个行(这种情况很少见),请用于(Import-Csv $_.FullName | Measure-Object).Count计算该Number of Rows字段,但请注意这会更慢。

笔记:

  • 如果您的 CSV 文件足够小以适合整个内存(一次一个),您可以通过使用(Get-Content $_.FullName).Count - 1计算行数来加快您的命令。

  • 请参阅此答案,了解为什么不建议使用迭代“扩展”数组+=,以及如何将偶数foreach循环用作表达式,其多个输出可以通过分配给变量直接收集在数组中。


推荐阅读