替代" -Contains"比较值而不是引用

时间:2017-08-14 16:42:19

标签: powershell boolean comparison equality object-reference

我有一个文件对象列表,我想检查给定的文件对象是否出现在该列表中。 -Contains运算符几乎是我正在寻找的,但似乎-Contains使用非常严格的相等性测试,其中对象引用必须相同。是否有一些不太严格的选择?我希望下面代码中的$boolean变量第二次和第一次返回True

PS C:\Users\Public\Documents\temp> ls


    Directory: C:\Users\Public\Documents\temp


Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-a----       14.08.2017     18.33              5 file1.txt
-a----       14.08.2017     18.33              5 file2.txt


PS C:\Users\Public\Documents\temp> $files1 = Get-ChildItem .
PS C:\Users\Public\Documents\temp> $files2 = Get-ChildItem .
PS C:\Users\Public\Documents\temp> $file = $files1[1]
PS C:\Users\Public\Documents\temp> $boolean = $files1 -Contains $file
PS C:\Users\Public\Documents\temp> $boolean
True
PS C:\Users\Public\Documents\temp> $boolean = $files2 -Contains $file
PS C:\Users\Public\Documents\temp> $boolean
False
PS C:\Users\Public\Documents\temp>

1 个答案:

答案 0 :(得分:1)

Get-ChildItem返回[System.IO.FileInfo]类型的对象。

Get-ChildItem  C:\temp\test\2.txt | Get-Member | Select-Object TypeName -Unique

TypeName
--------
System.IO.FileInfo

正如评论中提到的PetSerAl [System.IO.FileInfo]未实现IComparable或IEquatable。

[System.IO.FileInfo].GetInterfaces()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     False    ISerializable

如果没有这些,您注意到PowerShell只支持引用相等。 Lee Holmes'有一个很棒的blog post on this

然后,解决方案是对可比较的子属性进行比较。您可以选择一个独特的特定属性,例如Mathias R Jessen提到的Fullname。缺点是如果其他属性不同,则不会对它们进行评估。

'a' | Out-File .\file1.txt
$files = Get-ChildItem .
'b' | Out-File .\file1.txt
$file = Get-ChildItem .\file1.txt
$files.fullname -Contains $file.fullname

True

或者,您可以使用Compare-Object cmdlet来比较两个对象之间的所有属性(或者您使用-Property选择的特定属性)。

使用-IncludeEqual -ExcludeDifferent的{​​{1}}标志,我们可以找到具有匹配属性的所有对象。然后,当一个数组转换为Compare-Object时,如果它是非空的,则为[bool],如果为空,则为$True

$False

'a' | Out-File .\file1.txt $files = Get-ChildItem . $file = Get-ChildItem .\file1.txt [bool](Compare-Object $files $file -IncludeEqual -ExcludeDifferent) True 'a' | Out-File .\file1.txt $files = Get-ChildItem . 'b' | Out-File .\file1.txt $file = Get-ChildItem .\file1.txt [bool](Compare-Object $files $file -IncludeEqual -ExcludeDifferent) False 可能会占用大量资源,因此在可能的情况下最好使用其他形式的比较。