'获取-ChildItem -包含/-排除'如果作为参数传递给函数,PowerShell 中不会过滤

发布于 2024-08-20 10:12:54 字数 777 浏览 2 评论 0原文

我在获取 Get-ChildItem 的筛选器参数时遇到问题功能。

以下工作正常并显示完整的文件列表:

c:\temp\Get-ChildItem -Include *deleteme*.txt -Recurse

现在假设我有以下脚本

#file starts here
#filename = GetLastFile.ps1

param([string] $filter)

$files = Get-ChildItem $filter

Write-Host $files #should print all matching files but prints nothing

$file = $files | Select-Object -Last 1;


$file.name  #returns filename
#File ends here

现在尝试运行该脚本,但

c:\temp.\GetLastFile.ps1 "-Include *deleteme*.txt -Recurse"

没有返回任何内容。

提供过滤器 *.* 效果很好。由于 -Include-Exclude ,它似乎失败了。有什么想法吗?

I have a problem getting a filter argument to Get-ChildItem in a function.

The following works fine and displays a whole list of files:

c:\temp\Get-ChildItem -Include *deleteme*.txt -Recurse

Now say I have the following script

#file starts here
#filename = GetLastFile.ps1

param([string] $filter)

$files = Get-ChildItem $filter

Write-Host $files #should print all matching files but prints nothing

$file = $files | Select-Object -Last 1;


$file.name  #returns filename
#File ends here

Now trying to run the script,

c:\temp.\GetLastFile.ps1 "-Include *deleteme*.txt -Recurse"

returns nothing.

Supplying a filter, *.*, works fine. It seems to be failing due to the -Include or -Exclude. Any ideas?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

苦笑流年记忆 2024-08-27 10:12:54

您正开始进入 Powershell 2.0 代理功能可以提供帮助的领域。然而,除此之外,PowerShell 2.0 中还有一种简单的方法可以实现此目的,假设您只需要 -Include 和 -Recurse。实际上,我建议使用 -Filter 来代替它,它会做你想要的事情,坦率地说,它的速度要快得多(在我的一些测试中是 4 倍),因为 -filter 使用操作系统提供的文件系统过滤,而 -include 由 PowerShell 处理。

param([string]$Filter, [switch]$Recurse)

$files = Get-ChildItem @PSBoundParameters

Write-Host $files #should print all matching files but prints nothing

$file = $files | Select-Object -Last 1;

$file.name #returns filename

@ 符号用于将数组或哈希表“分布”到命令的参数中。 $PSBoundParameters 变量是 PowerShell 2.0 中新增的自动变量,在函数中定义。它是一个包含所有有界(命名和位置)参数的哈希表,例如:

PS> function foo($Name,$LName,[switch]$Recurse) { $PSBoundParameters }
PS> foo -Name Keith Hill -Recurse

Key                                                         Value
---                                                         -----
Name                                                        Keith
Recurse                                                     True
LName                                                       Hill

当您针对命令使用这样的哈希表时,PowerShell 会将键的(例如 Recurse)值映射到命令上名为 Recurse 的参数。

You're starting to get into an area where where Powershell 2.0 proxy functions can help. However, short of that, here's a simple way in PowerShell 2.0 to do this assuming all you need is -Include and -Recurse. Actually, I would recommend using -Filter instead it will do what you want and frankly it's quite a bit faster (4x on some of my tests) because -filter uses filesystem filtering provided by the OS whereas -include is processed by PowerShell.

param([string]$Filter, [switch]$Recurse)

$files = Get-ChildItem @PSBoundParameters

Write-Host $files #should print all matching files but prints nothing

$file = $files | Select-Object -Last 1;

$file.name #returns filename

The @ symbol is used to "splat" an array or hashtable across the parameters to a command. The $PSBoundParameters variable is an automatic variable new to PowerShell 2.0 that is defined in functions. It's a hashtable that contains all the bounded (named and positional) parameters e.g.:

PS> function foo($Name,$LName,[switch]$Recurse) { $PSBoundParameters }
PS> foo -Name Keith Hill -Recurse

Key                                                         Value
---                                                         -----
Name                                                        Keith
Recurse                                                     True
LName                                                       Hill

When you splat a hashtable like this against a command, PowerShell will map the key's (e.g. Recurse) value to the parameter named Recurse on the command.

七分※倦醒 2024-08-27 10:12:54

我相信发生的情况是您的 $filter 参数被视为 Get-ChildItem 命令的单个字符串参数。因此,除非您有一个名为“-Ininclude deleteme.txt -Recurse”的目录,否则该命令将始终不返回任何内容。

至于解决你的问题,有很多方法可以解决它。更通用的方法之一可能是在传递 $filter 参数时切换程序行为,而不是传递整个过滤器字符串,只需传递“deleteme.txt”字符串。

I believe what is happening is your $filter parameter is being treated as a single string argument to the Get-ChildItem command. As such, unless you have a directory named "-Include deleteme.txt -Recurse", the command will always return nothing.

As for fixing your problem, well, there are a bunch of ways you could approach it. Probably one of the more versatile ways is to switch program behavior if the the $filter argument is passed, and instead of passing the entire filter string just pass the "deleteme.txt" string.

初心 2024-08-27 10:12:54

您可以使用 Invoke-Expression 来执行存储在变量中的命令。例如:

param([string] $filter)
$files = Invoke-Expression "Get-ChildItem $filter"

Write-Host $files

$file = $files | Select-Object -Last 1

$file.name

You can use Invoke-Expression to execute a command stored in a variable. For example:

param([string] $filter)
$files = Invoke-Expression "Get-ChildItem $filter"

Write-Host $files

$file = $files | Select-Object -Last 1

$file.name
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文