I have this code:
Get-ChildItem FOLDERNAMEHERE *.png| ForEach-Object { $_.Name } > fileNames.txt
It prints off a list of file Names, and I want to change it to out just print out an index of numbers instead of Names.
CodePudding user response:
To output sequence numbers starting with 1 (replace $i = 0 with $i = -1 to start with 0):
Get-ChildItem FOLDERNAMEHERE *.png |
ForEach-Object -Begin { $i = 0 } -Process { ( $i) }
Note that the variable $i lives on after this command, and, if it preexisted before running the command, effectively changes it, because the script blocks passed to ForEach-Object run directly in the caller's scope.
The increment assignment operation ( ) is wrapped in (...) so as to also output the incremented value (assignment statements produce no output by default).
As an aside:
GitHub issue #13772 proposes introducing an automatic index variable for use in pipelines, such as
$PSIndex, which would simplify the solution to:Get-ChildItem FOLDERNAMEHERE *.png | ForEach-Object { $PSIndex 1 }
Non-streaming alternative, using .., the range operator:
if ($count = (Get-ChildItem FOLDERNAMEHERE *.png).Count) {
1..$count
}
Note: Non-streaming means that the results of the Get-ChildItem call are collected in full, up front in order to determine the upper limit for the sequence numbers.
Similarly, the 1..$count range operation collects the elements between the range endpoints in an array up front before beginning to produce visible output. See the comments for a discussion.
In other words: Go with the streaming, ForEach-Object-based solution if the Get-ChildItem command produces a lot of output objects and you want to start emitting sequence numbers as quickly as possible.
