PowerShell 附加到 csv 标题列中的第一个可用行

PowerShell append to first available row in a headered column in csv

对 PowerShell 相当陌生,在 csv 文件中每个带标题的列的第一个可用行中附加数据时遇到了挑战。

我想将 foreach 用于每一列的数据类型,这些数据将独立于另一列的数据。列 headers 是 $headers = "Scope", "Drawing", "Submittal", "Database", "Estimate", "Sequence",带有 foreach 以定位它们的各个项目并将其附加到每一列。当前发生的问题是,因为每个 category/column 及其各自的 foreach 都会将其添加到单独的行中,因为前一行已经附加了另一个类别的数据's/column 的数据创建对角线附加数据。

每个 category/column 使用单独的 foreach 的原因是该类别正在为每个类别独立地查找和过滤文件。

以下是 CSV 文件中发生的情况:

| Scope | Drawing | Submittal | Database | Estimate | Sequence |
| ------| ------- |---------- |--------- |--------- |--------- |
| DATA01| empty   | empty     | empty    | empty    | empty    |
| empty | DATA11  | empty     | empty    | empty    | empty    |
| empty | empty   | DATA21    | empty    | empty    | empty    |
| empty | empty   | empty     | DATA31   | empty    | empty    |
| empty | empty   | empty     | empty    | DATA41   | empty    |
| empty | empty   | empty     | empty    | empty    | DATA51   |

这是 CSV 文件的预期结果:

| Scope | Drawing | Submittal | Database | Estimate | Sequence |
| ------| ------- |---------- |--------- |--------- |--------- |
| DATA01| DATA11  | DATA21    | DATA31   | DATA41   | DATA51   |         

这是正在处理的部分代码:

# Creates the CSV if it does not already exist
$headers = "Scope", "Mechanical Drawing", "Controls Submittal", "Database", "Estimate", "Sequence of Operations"
$psObject = New-Object psobject
foreach($header in $headers)
{
 Add-Member -InputObject $psobject -MemberType noteproperty -Name $header -Value ""
}
$psObject | Export-Csv $CsvFile -NoTypeInformation

foreach ($file in $ScopeList)
{
    $hash=@{
        "Scope" = $file.Fullname
    }
    $NewItem = New-Object PSObject -Property $hash
    Export-Csv $CsvFile -inputobject $NewItem -append -Force
}

foreach ($file in $DrawingList)
{
    $hash=@{
        "Drawing" = $file.Fullname
    }
    $NewItem = New-Object PSObject -Property $hash
    Export-Csv $CsvFile -inputobject $NewItem -append -Force
}

foreach ($file in $SubtmittalList)
{
    $hash=@{
        "Submittal" = $file.Fullname
    }
    $NewItem = New-Object PSObject -Property $hash
    Export-Csv $CsvFile -inputobject $NewItem -append -Force
}

foreach ($file in $DatabaseList)
{
    $hash=@{
        "Database" = $file.Fullname
    }
    $NewItem = New-Object PSObject -Property $hash
    Export-Csv $CsvFile -inputobject $NewItem -append -Force
}

foreach ($file in $EstimateList)
{
    $hash=@{
        "Estimate" = $file.Fullname
    }
    $NewItem = New-Object PSObject -Property $hash
    Export-Csv $CsvFile -inputobject $NewItem -append -Force
}

foreach ($file in $SequenceList)
{
    $hash=@{
        "Sequence" = $file.Fullname
    }
    $NewItem = New-Object PSObject -Property $hash
    Export-Csv $CsvFile -inputobject $NewItem -append -Force
}

正在使用的 PowerShell 版本是 5.1。 Windows 10 OS.

有人可以帮助我了解如何在不擦除另一列的现有数据行的情况下追加到同一行但不同的列吗?这是否可以通过展开或查看每个变量来完成${named}List

如果我正确理解了这个问题,您有 6 个“$file”项数组需要合并到一个 CSV 文件中。

然后不使用 6 个 foreach 循环,只使用一个索引循环并从各种列表创建对象

如果所有列表具有相同数量的项目

$result = for ($i = 0; $i -lt $ScopeList.Count; $i++) {
    [PsCustomObject]@{
        Scope     = $ScopeList[$i].FullName
        Drawing   = $DrawingList[$i].FullName
        Submittal = $SubtmittalList[$i].FullName
        Database  = $DatabaseList[$i].FullName
        Estimate  = $EstimateList[$i].FullName
        Sequence  = $SequenceList[$i].FullName
    }
}

# now save the result as CSV file
$result | Export-Csv -Path 'X:\Path\to\TheResult.csv' -NoTypeInformation

如果列表的长度不尽相同,您需要做一些额外的工作:

# get the maximum number of items of your lists
$maxItems = (($ScopeList, $DrawingList, $SubtmittalList, $DatabaseList, $EstimateList, $SequenceList) | 
            Measure-Object -Property Count -Maximum).Maximum

# loop over the maximum number of items and check each list 
# if the index $i does not exceed the max number of items for that list
$result = for ($i = 0; $i -lt $maxItems; $i++) {
    [PsCustomObject]@{
        Scope     = if ($i -lt $ScopeList.Count)      {$ScopeList[$i].FullName}      else { $null}
        Drawing   = if ($i -lt $DrawingList.Count)    {$DrawingList[$i].FullName}    else { $null}
        Submittal = if ($i -lt $SubtmittalList.Count) {$SubtmittalList[$i].FullName} else { $null}
        Database  = if ($i -lt $DatabaseList.Count)   {$DatabaseList[$i].FullName}   else { $null}
        Estimate  = if ($i -lt $EstimateList.Count)   {$EstimateList[$i].FullName}   else { $null}
        Sequence  = if ($i -lt $SequenceList.Count)   {$SequenceList[$i].FullName}   else { $null}
    }
}

# now save the result as CSV file
$result | Export-Csv -Path 'X:\Path\to\TheResult.csv' -NoTypeInformation

就像 Theo 发布的那样,这主要是有效的或使意图更接近目标。 在创建独立列表的每个 foreach 循环中,创建了另一个列表用于过滤列表并在 Theo 的以下部分中使用。

# loop over the maximum number of items and check each list 
# if the index $i does not exceed the max number of items for that list
$result = for ($i = 0; $i -lt $maxItems; $i++) {
    [PsCustomObject]@{
        Scope     = if ($i -lt $ScopeList.Count)      {$ScopeList[$i].FullName}      else { $null}
        Drawing   = if ($i -lt $DrawingList.Count)    {$DrawingList[$i].FullName}    else { $null}
        Submittal = if ($i -lt $SubtmittalList.Count) {$SubtmittalList[$i].FullName} else { $null}
        Database  = if ($i -lt $DatabaseList.Count)   {$DatabaseList[$i].FullName}   else { $null}
        Estimate  = if ($i -lt $EstimateList.Count)   {$EstimateList[$i].FullName}   else { $null}
        Sequence  = if ($i -lt $SequenceList.Count)   {$SequenceList[$i].FullName}   else { $null}
    }
}

# now save the result as CSV file
$result | Export-Csv -Path 'X:\Path\to\TheResult.csv' -NoTypeInformation

要获得 $maxItems,另一种方法是将默认值设置为 1,除非在提示用户输入其他信息时用户输入有关键字“列表”,这是如何实现的另一个挑战将值限制为大于或等于 1...