2017-08-14 103 views
1

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

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> 
+0

您使用的是什么版本的PowerShell? –

+0

'$ files2 = $ files1.Clone()'或使用'Where-Object' – wOxxOm

+1

'[bool](Compare-Object $ files2 $ file -IncludeEqual -ExcludeDifferent)' – BenH

回答

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只会支持引用相等。李福尔摩斯'有一个伟大的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标志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 

Compare-Object可能是资源密集型的,所以最好在可能时使用比较其他形式。

+0

在我的特殊情况下,这两种解决方案都是合适的。谢谢! – Magnus