创建新对象PSObject时出错

时间:2020-04-13 13:46:03

标签: powershell csv

此powershell脚本在一个csv文件中最多容纳8行,并通过复制各列,然后将其保存到结果文件中(将第一个结果文件保存得很好)将它们组合成一行。如果csv中有16行,则意味着要保存第二个结果文件,等等。

例如在rows.csv中:

第一场第二场第三场第四场

球拍球拍俱乐部

橙色香蕉芒果梨

在result1.csv中:

first1second1third1four11first2second2third2third2

球拍球拍俱乐部橙色香蕉芒果梨

我得到一个错误:

New-Object : Cannot convert 'System.Object[]' to the type 'System.Collections.IDictionary' required by parameter 'Property'. Specified method is not supported.
At C:csv.ps1:19 char:42
+ $results = New-Object PSObject -Property $details
+                                          ~~~~~~~~
    + CategoryInfo          : InvalidArgument: (:) [New-Object], ParameterBindingException
    + FullyQualifiedErrorId : CannotConvertArgument,Microsoft.PowerShell.Commands.NewObjectCommand

请注意,第一个新对象的创建在第16行工作正常。在Powershell ISE中,如果我重新运行脚本,它在第16行也会出错。我不知道这里出了什么问题,但是假设我需要在保存每个csv文件后销毁PSObject?

$csvObjects = import-csv C:\rows.csv
$results = @()
$counter=1
foreach ($item in $csvObjects){
    $detailsnew = [ordered] @{            
        "first$counter" = $item.'First_field'          
        "second$counter" = $item.'Second_field'           
        "third$counter"  = $item.'Third_field'
        "fourth$counter" = $item.'Fourth_field'
    }   
    $details  +=  $detailsnew 
    # modulus comparison returns remainder - write out file every 8
    if ($counter % 8 -eq 0) {
        if ($counter -eq 8) {
            #works on line below on first run but fails on subsequent runs within Powershell ISE
            $results = New-Object PSObject -Property $details 
        }

        if ($counter -eq 16) {
            # fails on line below
            $results2 = New-Object PSObject -Property $details
        }

        $quotient = $counter / 8
        $results | export-csv -Path c:\result"$quotient".csv -noType
        $details = @()
        $results = @()
    }                     
    $counter++           
}
#write out final file if number not divisible by 8
if (-not($counter % 8 -eq 0)) {
    $results += New-Object PSObjectF -Property $details
    $modulo = $counter % 8
    $quotient_plus1 = (($counter-$modulo) / 8) +1
    $results | export-csv -Path C:\result"$quotient_plus1".csv -noType 
}

1 个答案:

答案 0 :(得分:4)

tl; dr

  • $details = @()应该是$details = [ordered] @{}

  • 要使ISE中的重复执行 按预期工作,请将另一个 $details = [ordered] @{}语句放在之前


  • 在第一次循环迭代中,$details最初是未定义,并且$details += $detailsnew分配了$detailsnew(有序)哈希表({ PowerShell中的{1}}哈希表的类型为System.Collections.Specialized.OrderedDictionary,按{em>原状的类型为[ordered] @{ ... }(即,$details未定义,$details有效地表现为与+=相同)。

  • 然后在{7}中将在接下来的7个迭代中创建的=哈希表合并到已经存储在$detailsnew中的哈希表中。 / p>

  • 在第8次迭代之后,您错误地将+=初始化为 array $details),这是问题的根源:后续使用$details然后向@()添加一个 new数组元素而不是合并哈希表条目,并传递一个 array 而不是哈希表(或任何实现System.Collections.IDictionary的字典类型)到+=的{​​{1}}参数,然后-可以预测-失败。

    • 相反,$details被(重新)初始化为有序哈希表:New-Object

在Powershell ISE中,如果我重新运行脚本,它也会在第16行出现错误。

运行的脚本 PowerShell ISE 点源 ,这意味着以前调用的变量可能会持续存在

顺便说一句:此同样适用于Visual Studio Code 及其PowerShell extension,您应该考虑将其迁移到 [1] 。 但是,您可以代替创建新的临时会话,如this answer底部所述。

在您的情况下,这意味着当您在ISE中重新执行脚本时,-Property在第一次迭代中已经是一个 array


[1] PowerShell ISE是no longer actively developedthere are reasons not to use it(底部)。

相关问题