将目录的父级与where管道中的另一个目录进行比较

时间:2010-06-29 18:50:31

标签: powershell powershell-v2.0

想象一下,我有一个像这样的目录结构:

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编码风格,或者指出更快/更正确的方法)

2 个答案:

答案 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