我正在使用Powershell脚本来比较目录,我希望尽可能清理一些代码。整个脚本的工作方式与我想要的完全一样,但我觉得下面包含的代码(只是其中的一小部分)可以写得更好。
对于下面的代码,它侧重于从csv文件中获取排除项并将它们合并到Get-ChildItem中。我发现你不能以与文件相同的方式从csv中拉出被排除的路径(因为路径处理FullName vs Name,加上包含文件夹和服务器的通配符)。
所以我下面的内容对我有用。但是有没有办法让Where-Object部分处理将路径排除到函数中,因为我必须调用它两次?我试过把它变成一个功能并在最后处理它,但这不起作用。我也尝试将它作为一个函数放在开头,但那也没有用。我知道当你处理函数和管道数据时,你必须以特定的方式设置它。所以也许我只是做错了什么。无论如何,如果你有关于如何清理它或提高效率的建议,我很乐意看到你拥有的东西。
$ExcludedPaths = @(Import-Csv -LiteralPath 'D:\ExclusionList.csv') |Select-Object -Expand ExcludedPaths
$ExcludedFiles = @(Import-Csv -LiteralPath 'D:\ExclusionList.csv') |Select-Object -Expand ExcludedFiles
$SourceFiles = Get-ChildItem -Recurse -Path $SourceDir -Exclude $ExcludedFiles -Force | Where-Object {
$FullName = $_.FullName
-not($ExcludedPaths|Where-Object {
$FullName -like "$_*"
})
}
$DestFiles = Get-ChildItem -Recurse -Path $DestDir -Exclude $ExcludedFiles -Force | Where-Object {
$FullName = $_.FullName
-not($ExcludedPaths|Where-Object {
$FullName -like "$_*"
})
}
答案 0 :(得分:0)
将脚本中的逻辑抽象为单独的函数非常简单。
我们首先确定例程的可变部分 - 这些将是我们的参数。在您的情况下,传递给-Path
的{{1}}和-Exclude
参数以及内部Get-ChildItem
的{{1}}数组。
通过重用与目标cmdlet($ExcludePaths
)相同的参数名称,我们可以轻松地展开Where-Object
变量,因此我们不必手动检查Get-ChildItem
参数是否通过了。与$PSBoundParameters
类似,无需进行其他检查,因为将-Exclude
应用于空数组将始终返回$ExcludePaths
。
所以我们最终得到的结果是:
-not
你的脚本最终变得更简单了:
$true
或者,您可以将用于function Get-ChildItemFiltered
{
param(
[Parameter(Mandatory)]
[string[]]$Path,
[string[]]$Exclude,
[string[]]$ExcludePaths
)
if($PSBoundParameters.ContainsKey('ExcludePaths')){
$PSBoundParameters.Remove('ExcludePaths')
}
Get-ChildItem -Recurse -Force @PSBoundParameters | Where-Object {
$FullName = $_.FullName
-not($ExcludePaths|Where-Object {
$FullName -like "$_*"
})
}
}
的过滤器存储在scriptblock中:
$SourceFiles = Get-ChildItem -Path $SourceDir -Exclude $ExcludedFiles -ExcludePaths $ExcludedPaths
$DestFiles = Get-ChildItem -Path $DestDir -Exclude $ExcludedFiles -ExcludePaths $ExcludedPaths