开发者

Comparing a directory's parent against another directory in a where pipe

开发者 https://www.devze.com 2023-01-05 16:18 出处:网络
Imagine I have a directory structure like so: parentDir\\dirA\\foo\\ parentDir\\dirB\\foo\\ parentDir\\dirC\\

Imagine I have a directory structure like so:

parentDir\dirA\foo\
parentDir\dirB\foo\
parentDir\dirC\
parentDir\dirD\bar\foo\
parentDir\dirE\foo\
parentDir\dirF\

I want to select only the directories that a) are immediate children of parentDir, and b) have a foo directory as an immediate child.

So dirs A, B, and E qualify, whilst C, D, and F don't.

I first tried this powershell script:

$rootDir = gi(".")
dir -include "*foo*" -recurse | ? {$_.PSIsContainer -eq $true} | % {$_.Parent} 
    | ? { $_.Parent -eq $rootDir } 

It finds all foo items below the root dir, filters out non-directories, goes up one to the intermediate directories, then filters out any directory which is not a child of the root dir.

This returns an empty list.

However if I change the last where clause as follows:

? { $_.Parent.FullName -eq $rootDir.Fullname }

It works, and I get the correct directories output.

So my question is, why won't a direct compare between di开发者_StackOverflowrectory objects work? It may seem like a little thing but it implies there's some hole in my understanding of powershell objects.

(Also, feel free to critique my powershell coding style in the scripts, or point out quicker/more correct ways of doing this)


When comparing .NET objects, there are a number of factors at play. First, the compare can be a simple reference equality comparison i.e. does this variable reference the exact same object that the other variable references. In many cases (most reference types), this is the default behavior for equality. There are other types (value types) however that do equality based the value of the fields in an object e.g. DateTime, TimeSpan, Int32, Double, etc. Then there are objects override the default behavior by overriding operator == or and/or overriding Equals() virtual method. String is a reference type that overrides these to provide "value-based" equality.

See if this does the trick:

$rootDir = gi .
gci . -r *Foo* | ?{$_.PSIsContainer -and $_.Name -eq 'Tools' -and `
                   $_.Parent.Name -eq $rootDir.Name}


Two different instances of the DirectoryInfo class are not considered equal, even if they point to the same path. Two strings on the other hand, are always considered equal if they contain the same letters, in the same order.

-Oisin

0

精彩评论

暂无评论...
验证码 换一张
取 消