$ Files中的PowerShell ForEach $ file [英] PowerShell ForEach $file in $Files
问题描述
我有一个PowerShell脚本,该脚本获取文件列表并移动符合特定条件的文件.为什么foreach
循环即使对象为空也要运行?
I have a PowerShell script that gets a file listing and moves the files that meet a specific criteria. Why does the foreach
loop run even if the object is empty?
我假设如果$ i不存在,它将不会运行.但是,如果$ filePath中没有结果,为什么forEach循环运行一次?我已经解决了这个问题,但是很好奇,我尝试搜索,但是找不到答案.
I would assume if $i did not exist it would not run. But if there are no results in $filePath why does the forEach loop run once? I have worked around my issue, but I am curious and I tried searching, but I could not find the answer.
要使其正常工作,我只需检查以确保$ filePath在forEach循环之前存在.
To get this to work I just check to make sure $filePath exists before the forEach loop.
例如,如果($ filePath){...
For example, if ($filePath){...
$filePath = Get-ChildItem -Path $sourceDir | Where-Object {! $_.PSIsContainer -AND ($_.Name -Match "^XXX_XXX*" -OR $_.Name -Match "^YYY_XX*")}
ForEach($i in $filePath){
$sfName = $i.Name
$sfDir = $i.Directory
$tFileName = testFile $destDir $sfName
$sFile = $sourceDir + $sfName
$tFile = $destDir + $tFileName
moveFile $sFile $tFile
推荐答案
这是PowerShell V3 IIRC中已解决的经典问题. PowerShell的foreach
循环将允许您遍历标量值,例如:
This is a classic issue that has been fixed in PowerShell V3 IIRC. PowerShell's foreach
loop will allow you to iterate over a scalar value e.g.:
foreach ($i in 1) {$i}
这很方便,因为您迭代的集合很多时候可以包含0、1或N个项目,例如:
That is handy because many times the collection you iterate can contain 0, 1 or N items e.g.:
$files = Get-ChildItem c:\temp\*.txt
foreach ($file in $files) {$file}
在这种情况下,Get-ChildItem
可以返回0、1或N个文件. N个文件很棒,我们可以对其进行迭代.但是,如果它返回了1个文件,然后您必须将该文件粘贴到数组中,以便可以使用foreach
-那样会很烂.因此,foreach
允许您迭代标量对象.当Get-ChildItem
返回0对象时,就会出现此问题.在这种情况下,未将空数组分配给$ files.而是分配了$ null. PowerShell将$ null视为标量,因此foreach
循环将在迭代值为$ null的情况下执行一次.真烂我和其他许多人都早早告诉了团队,因此在V3中,他们更改了foreach
,以使值不为$ null时,不对标量进行迭代.
In this case, Get-ChildItem
could return 0, 1 or N files. N files is great, we can iterate over that. However if it returned 1 file and then you had to stick that one file in an array so that you could use foreach
- well that would kind of suck. So foreach
allows you to iterate over a scalar object. The problem occurs when Get-ChildItem
returns 0 objects. In that case, an empty array is not assigned to $files. Instead $null is assigned. PowerShell considers $null a scalar and hence the foreach
loop will execute once where the iterated value is $null. That kind of sucks. And I and many other folks told the team this early on, so in V3 they changed foreach
to not iterate a scalar if the value is $null.
在V1/V2中解决此问题的另一种方法是确保空大小写生成一个空数组而不是$ null.您可以使用@()
数组表达式来做到这一点,例如
Another way to work around this in V1/V2 is to ensure the empty case generates an empty array instead of $null. You can do that using an @()
array expression e.g.
$files = @(Get-ChildItem c:\temp\*.txt)
foreach ($file in $files) {$file}
这将适用于0、1和N个文件.它适用于0个文件,因为@()
将导致将空数组分配给$ files.循环空数组时,foreach
不会执行其主体.
This will work for 0, 1, and N files. It's works for 0 files because the @()
will result in an empty array being assigned to $files. foreach
will not execute its body when looping over an empty array.
这篇关于$ Files中的PowerShell ForEach $ file的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!