powershell - 在数组中查找字符串 Powershell V2.0
问题描述
我遇到了在 PowerShell V5.0 中运行但在 V2.0 中无法运行的脚本的问题。
我需要比较两个 CSV 文件中的两列并编辑一个 CSV 中的一个值(如果两个文件中都存在该值)。
这是一个有问题的例子。$a
在 V5.0 中重命名为 1X,在 V2.0 中仍为 1。我尝试使用Compare
,但这并不能解决我的问题。不幸的是,不能在该特定机器上升级到 V5.0。您能提供的任何建议将不胜感激。
# create examples
$a = @()
$itema = New-Object PSObject
$itema | Add-Member -Type NoteProperty -Name 'ID' -Value '1'
$a += $itema
$b = @()
$itemb = New-Object PSObject
$itemb | Add-Member -Type NoteProperty -Name 'ID' -Value '1'
$b += $itemb
# problem
foreach ($value in $a) {
$ID = $value.ID
if ($b.ID -contains $ID) {$value.ID = $ID + "X"}
}
解决方案
PowerShell v2 不支持member enumeration,这是您在这里使用的:
$b.ID -contains $ID
该功能是在 PowerShell v3 中引入的。
在 PowerShell v2$b.ID
中尝试扩展arrayID
的属性,这会产生一个空结果,因为 array 对象没有这样的属性。 $b
在 PowerShell v3 和更新版本中,$b.ID
尝试扩展数组元素ID
的属性(如果数组对象本身没有该属性)。$b
要使您的代码与 PowerShell v2 兼容,请更改以下内容:
if ($b.ID -contains $ID) {$value.ID = $ID + "X"}
进入这个:
if (@($b | Select-Object -Expand ID) -contains $ID) {$value.ID = $ID + "X"}
附录:
出于性能原因,将 ID 列表仅在循环外展开一次并将其存储在单独的变量中是有意义的
$id_list = @($b | Select-Object -Expand ID)
然后在比较中使用该变量:
if ($id_list -contains $ID) {$value.ID = $ID + "X"}
如果您真的对性能有压力,我建议您从 ID 创建一个哈希表
$id_list = @{}
foreach ($e in $b) {
$id_list[$e.ID] = $true
}
并像这样进行比较:
if ($id_list.ContainsKey($ID)) {$value.ID = $ID + "X"}
Hashtable 查找比操作提供更好的性能,-contains
因为前者执行索引查找,而后者执行数组的线性搜索。
推荐阅读
- iot - ESP8266 WiFi 在没有 WiFiMulti 的情况下无法工作
- postgresql - TypeORM 基于枚举列和 FK 列创建约束?
- reactjs - 从 index.js 刷新 webfont 加载回调的子组件
- android - 收到通知时的异常
- c - 字符串数组的问题并在 C 中返回它们
- android - 安装没有成功。无法安装应用程序。安装失败,原因是:“无法安装 - 写入所有 apk”
- java - JFrame 调用正在打开两个 JFrame
- python - 在 Dockerfile 中从源代码安装 python 包
- django - 如何使用自定义 SQL 视图扩展 Django 的测试数据库?
- c# - 将查询结果存储到变量中