powershell:检查是否设置了一堆属性
powershell: Check if any of a bunch of properties is set
我正在导入一个如下所示的 csv 文件:
id,value1.1,value1.2,value1.3,Value2.1,Value2.2,Value3.1,Value3.2
row1,v1.1,,v1.3
row2,,,,v2.1,v2.2
row3,,,,,,,v3.2
现在我想检查是否设置了一组中的任何值属性。
我可以
Import-Csv .\test.csv | where {$_.Value1.1 -or $_.Value1.2 -or $_.Value1.3}
或
Import-Csv .\test.csv | foreach {
if ($_.Value1 -or $_.Value2 -or $_.Value3) {
Write-Output $_
}
}
但是我的 "real" csv 文件包含大约 200 列,我必须检查此 csv 中混合的 31 个属性 x 5 种不同的对象类型。所以我的代码会很丑。
有没有类似的
where {$_.Value1.*}
或
where {$ArrayWithPropertyNames}
?
您可以轻松地使用 Get-Member cmdlet 获取具有正确前缀的属性(只需在前缀后使用 *
作为通配符)。
因此,要实现您想要的效果,您只需根据具有正确前缀的任何属性是否包含数据来过滤数据。
下面的脚本使用您的示例数据,添加了 row4
,并过滤列表以查找在任何 属性 中具有值且以 value1
开头的所有项目。
$csv = @"
id,value1.1,value1.2,value1.3,Value2.1,Value2.2,Value3.1,Value3.2
row1,v1.1,,v1.3
row2,,,,v2.1,v2.2
row3,,,,,,,v3.2
row4,v1.1,,v1.3
"@
$data = ConvertFrom-csv $csv
$data | Where {
$currentDataItem = $_
$propertyValues = $currentDataItem |
# Get's all the properties with the correct prefix
Get-Member 'value1*' -MemberType NoteProperty |
# Gets the values for each of those properties
Foreach { $currentDataItem.($_.Name) } |
# Only keep the property value if it has a value
Where { $_ }
# Could just return $propertyValues, but this makes the intention clearer
$hasValueOnPrefixedProperty = $propertyValues.Length -gt 0
Write-Output $hasValueOnPrefixedProperty
}
替代解决方案:
$PropsToCheck = 'Value1*'
Import-csv .\test.csv |
Where {
(($_ | Select $PropsToCheck).psobject.properties.value) -contains ''
}
我正在导入一个如下所示的 csv 文件:
id,value1.1,value1.2,value1.3,Value2.1,Value2.2,Value3.1,Value3.2
row1,v1.1,,v1.3
row2,,,,v2.1,v2.2
row3,,,,,,,v3.2
现在我想检查是否设置了一组中的任何值属性。
我可以
Import-Csv .\test.csv | where {$_.Value1.1 -or $_.Value1.2 -or $_.Value1.3}
或
Import-Csv .\test.csv | foreach {
if ($_.Value1 -or $_.Value2 -or $_.Value3) {
Write-Output $_
}
}
但是我的 "real" csv 文件包含大约 200 列,我必须检查此 csv 中混合的 31 个属性 x 5 种不同的对象类型。所以我的代码会很丑。
有没有类似的
where {$_.Value1.*}
或
where {$ArrayWithPropertyNames}
?
您可以轻松地使用 Get-Member cmdlet 获取具有正确前缀的属性(只需在前缀后使用 *
作为通配符)。
因此,要实现您想要的效果,您只需根据具有正确前缀的任何属性是否包含数据来过滤数据。
下面的脚本使用您的示例数据,添加了 row4
,并过滤列表以查找在任何 属性 中具有值且以 value1
开头的所有项目。
$csv = @"
id,value1.1,value1.2,value1.3,Value2.1,Value2.2,Value3.1,Value3.2
row1,v1.1,,v1.3
row2,,,,v2.1,v2.2
row3,,,,,,,v3.2
row4,v1.1,,v1.3
"@
$data = ConvertFrom-csv $csv
$data | Where {
$currentDataItem = $_
$propertyValues = $currentDataItem |
# Get's all the properties with the correct prefix
Get-Member 'value1*' -MemberType NoteProperty |
# Gets the values for each of those properties
Foreach { $currentDataItem.($_.Name) } |
# Only keep the property value if it has a value
Where { $_ }
# Could just return $propertyValues, but this makes the intention clearer
$hasValueOnPrefixedProperty = $propertyValues.Length -gt 0
Write-Output $hasValueOnPrefixedProperty
}
替代解决方案:
$PropsToCheck = 'Value1*'
Import-csv .\test.csv |
Where {
(($_ | Select $PropsToCheck).psobject.properties.value) -contains ''
}