想象一下,我有一个像这样的目录结构:
parentDir\dirA\foo\
parentDir\dirB\foo\
parentDir\dirC\
parentDir\dirD\bar\foo\
parentDir\dirE\foo\
parentDir\dirF\
我想只选择a)是parentDir的直接子项的目录,b)将foo目录作为直接子项。
因此,A,B和E的目的地有资格,而C,D和F则没有。
我首先尝试了这个powershell脚本:
$rootDir = gi(".")
dir -include "*foo*" -recurse | ? {$_.PSIsContainer -eq $true} | % {$_.Parent}
| ? { $_.Parent -eq $rootDir }
它找到根目录下面的所有foo项,过滤掉非目录,上升到中间目录,然后过滤掉任何不是根目录子项的目录。
这会返回一个空列表。
但是,如果我更改最后一个where子句如下:
? { $_.Parent.FullName -eq $rootDir.Fullname }
它有效,我得到正确的目录输出。
所以我的问题是,为什么目录对象之间的直接比较不起作用?这似乎是一件小事,但这意味着我对powershell对象的理解存在一些漏洞。
(另外,请随意批评脚本中的powershell编码风格,或者指出更快/更正确的方法)
答案 0 :(得分:3)
比较.NET对象时,有许多因素在起作用。首先,比较可以是简单的引用相等比较,即该变量引用与另一个变量引用的完全相同的对象。在许多情况下(大多数引用类型),这是相等的默认行为。然而,存在其他类型(值类型),其基于对象中的字段的值进行相等,例如, DateTime,TimeSpan,Int32,Double等。然后有些对象通过重写operator ==或/和/或覆盖Equals()虚方法来覆盖默认行为。 String是一种引用类型,它会覆盖这些类型以提供“基于值”的相等性。
看看这是否有效:
$rootDir = gi .
gci . -r *Foo* | ?{$_.PSIsContainer -and $_.Name -eq 'Tools' -and `
$_.Parent.Name -eq $rootDir.Name}
答案 1 :(得分:2)
DirectoryInfo类的两个不同实例不被视为相等,即使它们指向相同的路径。另一方面,如果两个字符串包含相同的字母,则它们始终被视为相等。
-Oisin