powershell - 创建新对象 PSObject 时出错
问题描述
此 powershell 脚本在 csv 文件中最多占用 8 行,并通过复制列将它们组合成一行,然后保存在结果文件中(第一个结果文件保存良好)。如果 csv 中有 16 行,则意味着保存第二个结果文件等。
例如在 rows.csv 中:
第一场 第二场 第三场 第四场
球拍球拍俱乐部
橙香蕉芒果梨
在 result1.csv 中:
第一1 第二1 第三1 第四1 第一2 第二2 第三2 第四2
球 蝙蝠 球拍 俱乐部 橙色 香蕉 芒果 梨
我收到一个错误:
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
}
解决方案
tl;博士
$details = @()
应该$details = [ordered] @{}
要使ISE 的重复执行也按预期工作,请在循环之前放置另一个
$details = [ordered] @{}
语句。
在第一个循环迭代中,
$details
最初是undefined,$details += $detailsnew
并将$detailsnew
(有序的)哈希表([ordered] @{ ... }
PowerShell 中的哈希表类型为System.Collections.Specialized.OrderedDictionary
)按原样分配给$details
(即,在$details
未定义的情况下,+=
实际上行为与 相同=
)。$detailsnew
在接下来的 7 次迭代中创建的哈希表然后被合并+=
到已经存储在$details
.在第 8 次迭代之后,您错误地(重新)初始化
$details
为数组(一个哈希表(或任何实现的字典类型)到's参数然后 - 可以预见地 - 失败。@()
+=
$details
System.Collections.IDictionary
New-Object
-Property
- 相反,(重新)初始化
$details
为有序哈希表:$details = [ordered] @{}
- 相反,(重新)初始化
在 Powershell ISE 中,如果我重新运行脚本,它也会在第 16 行出错。
PowerShell ISE点源它运行的脚本,这意味着来自先前调用的变量可以保留。
顺便说一句:这同样适用于带有PowerShell 扩展的Visual Studio Code,您应该考虑将其迁移到[1]。但是,您可以选择创建一个新的临时会话,如本答案底部所述。
在您的情况下,这意味着当您在 ISE 中重新执行脚本时,它$details
已经是第一次迭代中的数组。
推荐阅读
- c++ - 为什么在使用原始头文件编译 TSS 文件时出现 typedef 错误?
- arrays - 如何根据指定的开始时间从数据框中提取多个 5 分钟平均值?
- javascript - 板球实时比分更新的客户端代码
- javascript - 如何在数组中获取过滤器值和总和值?
- c++ - 如何在 C++ 中创建一个指向整数和逗号串联的 char 指针?
- flutter - 如何编辑 Flutter 暗模式
- python - 使用 k 最近邻回归时拟合错误
- regex - 使用 RegEx 解析地址字段中的合法描述
- youtube - Youtube 视频嵌入缩略图
- kubernetes - 我可以让 NGinX 入口控制器代理外部(不在我的云中)资源吗?