PowerShell ForEach $Files 中的 $file [英] PowerShell ForEach $file in $Files

查看:20
本文介绍了PowerShell ForEach $Files 中的 $file的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 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:	emp*.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:	emp*.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.

这篇关于PowerShell ForEach $Files 中的 $file的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆