簡體   English   中英

PowerShell中的ForEach和ForEach-Object之間的區別

[英]Difference between ForEach and ForEach-Object in powershell

ForEachForEach-Object之間有什么區別嗎?

我有一個像這樣的小代碼,工作正常

$txt = Get-Content 'C:\temp\000.txt'
$result = foreach ($line in $txt) {$line.replace(".ini","")}
$result | out-file 'c:\temp\001.txt'

但如果我使用'ForEach-Object',我就會出錯......

$txt = Get-Content 'C:\temp\000.txt'
$result = foreach-object ($line in $txt) {$line.replace(".ini","")}
$result | out-file 'c:\temp\001.txt'

為什么? 以及如何使用ForEach-Object輸出循環結果

foreachForEach-Object的別名,但它似乎也是一個關鍵字(這令人困惑)。

您正在使用的foreach ($<item> in $<collection\\>){<statement list>}語法是help about_foreach

foreach作為ForEach-Object別名是help ForEach-Object

關鍵字foreach()位中給出的$<collection>中的每個$<item>進行操作。

別名foreach / function ForEach-Object對作為輸入接收的集合的每個項進行操作。

它們是用於不同目的的不同命令。 ForEach-Object cmdlet在管道中使用,您可以使用$ PSItem或$ _來引用當前對象,以便運行{scriptblock},如下所示:

1..5 | ForEach-Object {$_}

>1
>2
>3
>4
>5

現在,您還可以在行的開頭使用非常類似的關鍵字 ForEach。 在這種情況下,您可以運行{scriptblock}來定義變量名稱,如下所示:

ForEach ($number in 1..5){$number}
>1
>2
>3
>4
>5

這里的核心區別在於您使用命令的位置,一個用於管道中,另一個用於啟動自己的管道。 在生產樣式腳本中,我建議使用ForEach關鍵字而不是cmdlet。

以前的答案都是正確的,但https://blogs.technet.microsoft.com/heyscriptingguy/2014/07/08/getting-to-know-foreach-and-foreach-object/都有一個很好的總結:

當您將輸入傳遞給ForEach時,它是ForEach-Object的別名。 但是當您將ForEach放在行的開頭時,它是一個Windows PowerShell語句。

更多細節:

ForEach語句將所有項目預先加載到集合中,然后逐個處理它們。 ForEach-Object期望項目通過管道流式傳輸,從而降低了內存需求,但同時也降低了性能。

然后他包括一些性能測量並得出結論:

那么你用哪一個? 嗯,答案是“它取決於。”您可以使用ForEach語句或ForEach-Object cmdlet迭代項集合。 ForEach是完美的,如果你有足夠的內存,想要最好的性能,而不關心通過管道將輸出傳遞給另一個命令。 ForEach-Object(及其別名%和ForEach)從管道獲取輸入。 雖然處理所有內容的速度較慢,但​​它為您提供了Begin,Process和End塊的優勢。 此外,它允許您通過管道將對象流式傳輸到另一個命令。 最后,使用最符合您要求的方法和系統的功能。

除了前面提到的技術差異之外,為了完整起見,這里有一些實際差異( 另見 ):

1.)在管道中,您不知道已處理項目的總數。 在這種情況下,您可以先選擇獲取完整列表,然后再執行foreach循環。

例:

$files = gci "c:\fakepath"
$i = 0
foreach ($file in $files) {
    $i++
    Write-Host "$i / $($files.Count) processed"
}

2.)使用現有列表, foreach循環比管道版本更快,因為每次都不必調用腳本塊。 (但根據您的工作和項目數量的不同,差異可能微不足道。)

例:

$items = 0..100000
Measure-Command { $items | ForEach-Object { $_ } }
# ~500ms on my machine
Measure-Command { foreach ($i in $items) { $i } }
# ~70ms on my machine

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM