Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

Recently, I've been playing with PowerShell, and I've noticed some weird behavior when using pipes and foreach loops that I couldn't understand.

This simple code works:

$x = foreach ($i in gci){$i.length}
$x | measure -max

Makes sense.

But this code won't:

foreach ($i in gci){$i.length} | measure -max

And I'm getting the following error:

An empty pipe element is not allowed.
At line:1 char:33
+ foreach ($i in gci){$i.length} | <<<<  measure -max
+ CategoryInfo          : ParserError: (:) [], ParentContainsErrorRecordException
+ FullyQualifiedErrorId : EmptyPipeElement

What is the difference between those two methods, and why does the second one fails?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
1.4k views
Welcome To Ask or Share your Answers For Others

1 Answer

The foreach statement doesn't use the pipeline architecture, so its output cannot be passed to a pipeline directly (i.e. item by item). To be able to pass output from a foreach loop to a pipeline you must run the loop in a subexpression:

$(foreach ($item in Get-ChildItem) { $item.Length }) | ...

or collect it in a variable first:

$len = foreach ($item in Get-ChildItem) { ... }
$len | ...

If you want to process data in a pipeline use the ForEach-Object cmdlet instead:

Get-ChildItem | ForEach-Object { $_.Length } | ...

For further explanation of the differences between foreach statement and ForEach-Object cmdlet see the Scripting Guy blog and the chapter on loops from Master-PowerShell.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...