2010-06-29 61 views
1

想象我有一個目錄結構如下所示:在一個目錄的父對另一目錄比較,其中管

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

我只想選擇一個)是parentDir的直接孩子的目錄,以及b)有作爲直接孩子的foo目錄。

因此,A,B和E的展位符合資格,而C,D和F則不符合。

我第一次嘗試這樣PowerShell腳本:

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

它發現的根目錄下的所有富項目,過濾掉非目錄,上升一到中間的目錄,然後過濾掉這不是任何目錄根目錄的孩子。

這將返回一個空列表。

但是,如果我改變最後的where子句如下:

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

它的工作原理,我也得到了目錄輸出正確的。

所以我的問題是,爲什麼不能直接比較目錄對象的工作?它可能看起來像一件小事,但它意味着我對PowerShell對象的理解存在一些漏洞。

即使(而且,隨意批評的劇本我PowerShell的編碼風格,或指出更快/更正確的這樣做的方法)

+2

我可能會寫爲'GCI | ?{$ _。psiscontainer-和(測試路徑$ _ \ foo)}'... – Joey 2010-06-29 18:57:11

+0

@Johannes羅塞爾嘿,這更簡潔;謝謝。 – tenpn 2010-06-29 19:02:36

回答

3

當比較.NET對象時,有許多因素在起作用。首先,比較可以是簡單的參考相等比較,即該變量是否引用與其他變量引用完全相同的對象。在許多情況下(大多數參考類型),這是平等的默認行爲。然而,還有其他類型(值類型),它們基於對象中字段的值進行相等,例如DateTime,TimeSpan,Int32,Double等。然後有對象通過覆蓋運算符==或/和重寫Equals()虛擬方法來覆蓋默認行爲。字符串是一種引用類型,它會覆蓋這些以提供「基於值」的相等性。

看看這樣做的伎倆:

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

謝謝。我想知道-eq是否是參考比較者或價值,以及是否有某種方法可以使其成爲後者。但是從你所說的話來看,它純粹歸功於我正在使用的.Net類。在將來,我將不得不檢查MSDN,看看我正在使用的類是否支持相等(在本例中爲System.IO.DirectoryInfo)。 – tenpn 2010-06-30 06:51:00

2

兩個DirectoryInfo類的不同實例並不認爲是相等的,他們指向相同的路徑。另一方面,如果兩個字符串按照相同的順序包含相同的字母,則總是被認爲是相等的。

-Oisin