2

我正在尝试拆分从 csv 文件中读取的数组,但除了第一个数组元素之外,我无法捕获任何内容。这是我的代码

$EmployeeLists = @()
$ManagerLists = @()

$CSVFiles = Import-CSV "C:\T2\SetManagers\EmployeeManager.csv"

ForEach($CSVFile in $CSVFiles) { $EmployeeLists += ($CSVFile.Employee) }
ForEach($CSVFile in $CSVFiles) { $ManagerLists += ($CSVFile.Manager) }

ForEach($EmployeeList in $EmployeeLists) { $EmployeeLists.Split(",")[0] | Out-File "C:\T2\SetManagers\ESplit.txt" -Append }
ForEach($ManagerList in $ManagerLists) { $ManagerLists.Split(",")[0] | Out-File "C:\T2\SetManagers\MSplit.txt" -Append }

我的 put put 看起来像这样

Smith
Smith
Smith
Smith
Smith
Smith
Smith
4

2 回答 2

2

正确的格式有很长的路要走:

$csv = Import-Csv -Path C:\T2\SetManagers\EmployeeManager.csv

foreach ($list in $csv) {
    $list.Employee.Split(',')[0] | Out-File -Path C:\T2\SetManagers\ESplit.txt -Append
    $list.Manager.Split(',')[0] | Out-File -Path C:\T2\SetManagers\MSplit.txt -Append
}

您的问题是指整个列表而不是foreach循环中的单个元素。

于 2018-07-16T18:31:24.527 回答
2

TheIncorrigible1 的有用答案解释了您的代码存在的问题并提供了有效的解决方案。

  • 如果您对(固定)代码的性能感到满意,并且您认为没有必要改进您的代码,那么这就是您所需要的。

  • 要了解缩短和加速代码的可重用技术,请继续阅读。


一个简洁的、PowerShell 惯用的解决方案,性能要好得多(PSv4+):

# Read the CSV rows (into custom objects whose properties contain the
# column values).
$rows = Import-CSV "C:\T2\SetManagers\EmployeeManager.csv"

# Collect all Employee and Manager column values in an array each.
$employeeLists = $rows.Employee
$managerLists = $rows.Manager

# Loop over all column values, extract only the first ","-separated token each
# and send the combined output to an output file.
$employeeLists.ForEach({ ($_ -split ',')[0] }) > "C:\T2\SetManagers\ESplit.txt"
$managerLists.ForEach({ ($_ -split ',')[0] }) >  "C:\T2\SetManagers\MSplit.txt"

具体来说,上面的代码避免了

  • 使用循环构建数组,+=这需要在每次迭代中重新创建数组(附加新值)。

    • 相反,它使用成员枚举 (PSv3+) 直接检索属性值数组(例如,$employeeLists = $rows.Employee

    • 即使在 PSv2 中,也可以使用相对简洁和更有效的形式;PSv2 相当于$employeeLists = $rows.Employee

      # *PowerShell* does the work of collecting the outputs from the individual
      # loop iterations and simply returns an array.
      $employeeLists = foreach ($row in $rows) { $row.Employee }
      
    • 最后,如果您确实需要迭代地构建集合并加快速度,请使用可扩展的集合类型,例如[System.Collections.Generic.List[object]]及其.Add()方法,而不是使用+=.

  • Out-File循环中调用,这会在每次迭代中产生 cmdlet 的启动和拆卸成本,并且每次都需要重新打开和关闭文件。

    • 相反,语句的组合输出在一次 调用中写入输出文件Out-File(为简洁起见,缩写>为)。
  • 与循环相比,PSv4+.ForEach() 方法的性能更好(虽然只是略微),并且具有可以直接将其用作管道的第一段的优点(而循环需要在 中进行包装)。 在 PSv3- 中,使用循环。foreach foreach$(...)
    foreach

于 2018-07-16T19:21:19.680 回答