2017-08-14 99 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