2016-11-21 37 views
1

所以,我繼續與像這樣的任務麻煩:如何管理處理從另一個對象擴展的字符串列表?

$fileNames = Get-ChildItem -Path . -Filter "*.*" ` 
    | Select-Object -ExpandProperty Name 

$fileNames.GetType() 

我期望輸出爲字符串[],但它的對象[]。

更糟的是,如果我再嘗試操作的文件名:

$fileNames = Get-ChildItem -Path . -Filter "*.*" ` 
    | Select-Object -ExpandProperty Name ` 
    | Select-Object { "$_" -replace '^.*deploy\.log\.\d\d\d\d-\d\d-\d\d\.', '' } 

我再次想到的String []。相反,我得到一些奇怪的哈希表,作爲正則表達式的關鍵。

在這兩種情況下,它都按我期望的那樣做,只是將它包裝在對象中。

這裏有什麼規則?我可以只操縱一串字符串嗎?

回答

4

正如你上一個管道元件,使用ForEach-Object代替Select-Object

$fileNames = Get-ChildItem -Path . -Filter "*.*" ` 
    | Select-Object -ExpandProperty Name ` 
    | ForEach-Object { "$_" -replace '^.*deploy\.log\.\d\d\d\d-\d\d-\d\d\.', '' } 

可以跳過Select-Object -Expand部分完全,如果你想:

$fileNames = Get-ChildItem -Filter *.* | ForEach-Object { 
    $_.Name -replace '^.*deploy\.log\.\d\d\d\d-\d\d-\d\d\.', '' 
} 
+0

所以的foreach對象更像是地圖。即它將函數應用於每個項目並返回一個列表?而不是像Linq的ForEach那樣對每個項目採取行動,但不返回任何內容? –

+1

'ForEach-Object'就像是一個'map'函數,是的。從每次迭代返回項目是可選的 –

5

你的第一個代碼段的結果是一個通用數組(因此它的類型表示爲Object[]),但元素實際上是字符串。如果由於某種原因,你需要的類型是string[]可將變量簡單地強制轉換爲類型:

[string[]]$filenames = Get-ChildItem ... | Select-Object -Expand Name 

通常情況下,不應該是必要的,但。

在您的第二個代碼片段中,您可能會混淆Select-ObjectForEach-Object(請參閱Mathias' answer)。而是採用了ForEach-Object循環的,你也可以直接使用-replace操作上擴展名:

$filenames = (Get-ChildItem ... | Select-Object -Expand Name) -replace '^.*deploy\.log\.\d{4}-\d{2}-\d{2}\.', '' 
+0

謝謝。所以-replace在列表上工作?並將其應用於每個項目並返回一個列表? –

+1

這是正確的。 –