如何在PowerShell的ForEach-Object中递增索引变量?
PowerShell脚本执行次数异常问题分析与解决
你遇到的问题是:用逗号连接两个Get-ChildItem命令获取不同扩展名的文件后,后续管道到Sort-Object和ForEach-Object时,计数逻辑始终只执行一次,但将表达式替换为$_却能返回所有文件行。
问题原因
核心问题出在逗号的使用逻辑:
(Get-ChildItem -Filter '*.png'), (Get-ChildItem -Filter '*.jpg')会把两个命令的输出包装成两个独立的数组对象传入管道,而非将所有文件对象平铺为连续的单数据流。Sort-Object会分别对每个数组内部的元素排序,再将排序后的数组依次传给ForEach-Object。ForEach-Object的Process块默认处理管道传入的顶层对象(即每个数组),而非数组内的单个文件。因此计数逻辑++$idx; $idx只会针对每个数组执行一次,而非每个文件执行一次。- 当你在
Process块中写$_时,PowerShell输出数组对象会自动展开其内部元素,所以看起来返回了所有文件行,但本质是两次输出数组(每个数组展开为元素)。
解决方法
方法1:用管道连接两个Get-ChildItem
将逗号替换为管道,让两个命令的输出直接合并为单数据流:
Get-ChildItem -Filter '*.png' | Get-ChildItem -Filter '*.jpg' | Sort-Object -Property 'Name' | ForEach-Object -Begin { $idx = 0 } -Process { ++$idx; $idx; }
方法2:用-Include参数一次性获取多扩展名文件
更简洁的写法,直接通过Get-ChildItem的-Include参数指定多个扩展名(若不需要遍历子目录可去掉-Recurse):
Get-ChildItem -Include '*.png', '*.jpg' -Recurse | Sort-Object -Property 'Name' | ForEach-Object -Begin { $idx = 0 } -Process { ++$idx; $idx; }
方法3:展开逗号生成的数组
若坚持用逗号写法,需先将数组展开为单个元素流,可借助Write-Output实现:
Write-Output (Get-ChildItem -Filter '*.png'), (Get-ChildItem -Filter '*.jpg') | Sort-Object -Property 'Name' | ForEach-Object -Begin { $idx = 0 } -Process { ++$idx; $idx; }
内容的提问来源于stack exchange,提问作者AxD
相关产品推荐
相关产品推荐

