在一个数组中加入两个或多个Get-ChildItem调用的最简洁方法是什么?

时间:2012-10-18 11:16:54

标签: powershell powershell-v2.0

我遇到了使用PowerShell在文件系统上移动和复制某些项目的问题。

我通过实验了解到,即使使用PowerShell v3,cmdlet Copy-ItemMove-ItemDelete-Item 也无法正确处理重新分析点,如符号链接,如果与开关-Recurse一起使用,可能会导致灾难。

我想阻止这种情况。我必须每次运行两个或更多文件夹,所以我想到这样的事情。

$Strings = @{ ... }
$ori = Get-ChildItem $OriginPath -Recurse
$dri = Get-ChildItem $DestinationPath -Recurse

$items = ($ori + $dri) | where { $_.Attributes -match 'ReparsePoint' }
if ($items.Length -gt 0)
{
    Write-Verbose ($Strings.LogExistingReparsePoint -f $items.Length)
    $items | foreach { Write-Verbose "    $($_.FullName)" }
    throw ($Strings.ErrorExistingReparsePoint -f $items.Length)
}

这不起作用,因为$ori$dri也可以是单个项而不是数组:op-Addition将失败。改为

$items = @(@($ori) + @($dri)) | where { $_.Attributes -match 'ReparsePoint' }

带来了另一个问题,因为$ori$dri也可能是$null,我可以用包含$null的数组结束。将连接结果重新连接到Where-Object时,我可以再次使用$null,单个项目或数组。

唯一显而易见的解决方案是遵循更复杂的代码

$items = $()
if ($ori -ne $null) { $items += @($ori) }
if ($dri -ne $null) { $items += @($dri) }
$items = $items | where { $_.Attributes -match 'ReparsePoint' }

if ($items -ne $null)
{
    Write-Verbose ($Strings.LogExistingReparsePoint -f @($items).Length)
    $items | foreach { Write-Verbose "    $($_.FullName)" }
    throw ($Strings.ErrorExistingReparsePoint -f @($items).Length)
}

有一些更好的approch?

我很有兴趣确定是否有办法以正确的方式处理PowerShell cmdlet的重新分析点,但我更有兴趣知道如何加入和过滤两个或更多“PowerShell集合”

我总结观察到,目前,PowerShell的这个“多态数组”的特性对我来说并没有这么大的好处。

感谢阅读。

2 个答案:

答案 0 :(得分:1)

只需添加一个过滤器即可抛出空值。你走在正确的轨道上。

$items = @(@($ori) + @($dri)) | ? { $_ -ne $null }

答案 1 :(得分:0)

我已经在Powershell 3上工作了一段时间,但从我能说的这个也应该在2.0中工作:

$items = @($ori, $dri) | %{ $_ } | ? { $_.Attributes -match 'ReparsePoint' }

基本上%{ $_ }是一个foreach循环,它通过迭代内部数组并将每个内部元素($_)传递到管道中来展开内部数组。 Null将自动从管道中排除。