Powershell输出txt文件中的记录列表

Powershell to output a list of records in a txt file

在PowerShell中运行以下内容

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
$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是否有可能列出所有文件名以及可能的相应行数

谢谢


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

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

1
2
3
4
5
6
$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
  }
}

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

注意:

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

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


与mklement0的答案类似,但我认为我只是将信息添加到您已经获得的现有文件信息中。

1
2
$listOfFiles = Get-ChildItem C:\\temp -Recurse -Filter *.csv | Select-Object *,@{l='Number of Rows';e={(Get-Content $_.FullName | Measure-Object -Line).Lines - 1}}
$listOfFiles | Select Name,'Number of Rows' | Export-Csv 'c:\\test\\output.csv' -NoTypeInformation

您似乎在变量$files中出现Get-Content,但在另一个数组上进行了迭代。

Write-Host对您有用,因为它在循环内。

您的追加似乎在循环之外,并且您正在调用一个尚未构建的文件(至少在提供的摘录中)。

如果使用格式化标准,则更容易注意到诸如掉入循环之类的东西。

正如Compo所提到的,可以使用一些更快的方法来实现您要寻找的目标。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
$businessFiles = Get-ChildItem -Path 'C:\\temp\' -Recurse -Filter '*.csv'
[System.Collections.ArrayList]$listOfFiles = @()

foreach ($businessFile in $businessFiles) {
    $file = Import-Csv $BusinessFile.fullname
    $businessNumRows = $file.Count

    Write-Host 'Business File Name: ' $businessFile.name
    Write-Host 'Number of Rows: ' $businessNumRows -ForegroundColor Yellow  

    $record = @{
        'File Name' = $businessFile.Name
        'Number of Rows' = $businessNumRows
    }
    $recordObj = New-Object -TypeName PSObject -Property $record
    $listOfFiles.Add($recordObj) > $null
}

$listOfFiles | Export-Csv 'c:\\test\\output.csv' -NoTypeInformation
Invoke-Item 'c:\\test\\output.csv'