数组第一个元素

时间:2018-07-16 18:22:18

标签: arrays powershell import-csv

我正在尝试分割数组以读取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 }

我的看跌期权看起来像这样

Smith
Smith
Smith
Smith
Smith
Smith
Smith

2 个答案:

答案 0 :(得分: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循环中的单个元素。

答案 1 :(得分:2)

TheIncorrigible1's helpful answer解释了您的代码存在的问题并提供了有效的解决方案。

  • 如果您对(固定)代码的性能感到满意,并且发现不需要改进,则只需要这些。

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


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中,相对简洁和更有效的形式也是可能的; $employeeLists = $rows.Employee的PSv2等同于:

      # *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的启动和删除成本,并且每次都需要重新打开和关闭文件。

    • 相反,该语句的 combined 输出通过 single Out-File调用(为简便起见缩写为>)写入输出文件。 )。
  • PSv4 + .ForEach() 方法而不是foreach loop ,其性能更好(尽管略有提高),并且具有以下优点:您可以将其直接用作管道的第一部分(而foreach循环则需要包装在$(...)中)。
    在PSv3中,使用foreach循环。