PowerShell Where-Object 语句中的多个 -and -or
Posted
技术标签:
【中文标题】PowerShell Where-Object 语句中的多个 -and -or【英文标题】:Multiple -and -or in PowerShell Where-Object statement 【发布时间】:2014-09-01 04:56:37 【问题描述】:PS H:\> Invoke-Command -computername SERVERNAME Get-ChildItem -path E:\dfsroots\datastore2\public | Where-Object $_.e
xtension-match "xls" -or $_.extension-match "xlk" -and $_.creationtime -ge "06/01/2014"
以上是我的代码示例。我正在尝试在我的文件服务器上远程运行此 PowerShell 代码,并让它返回创建日期为 2014 年 6 月 1 日或之后的所有 .xls 和 .xlk 文件。当我运行此代码时,它开始吐出该远程位置的所有文件夹。如果我只比较这样的两件事:
PS H:\> Invoke-Command -computername SERVERNAME Get-ChildItem -path E:\dfsroots\datastore2\public | Where-Object $_.extension-match "xls" -and $_.creationtime -ge "06/01/2014"
仅显示在该日期或之后创建的 xls 文件。这里发生了什么?除了嵌套 -and
和 -or
语句之外,我还需要使用其他东西吗?
【问题讨论】:
请注意,将命令分解为多个“where”语句也不起作用。我会输入如下命令: PS H:\> Invoke-Command -computername SERVERNAME Get-ChildItem -path E:\dfsroots\datastore2\public | Where-Object $_.extension-match "xls" - 或 $_.extension-match "xlk" | where-object $_.creationtime -ge "06/01/2014" 它开始吐出 xlsx 文件,这不是我想要的。 使用圆括号而不是大括号来包围选项,所以Where($_.Extension -Match "xls" -or $_.Extension -Match "xlk") -and $_.CreationTime -ge "06/01/2014"
@TheMadTechnician 如果你能帮我一分钟,我不知道什么 mini-Markdown 格式有效,什么无效。您是如何将其包含在“代码”块中的?
@TheMadTechnician 即使使用括号,结果仍然会输出 xlsx 文件。
@WinskiTech 回复:Markdown。单击注释框旁边的帮助链接以获取格式化帮助。用反引号包围代码`
。
【参考方案1】:
通过在您的第一个示例中将您的比较包装在 中,您正在创建脚本块;因此 PowerShell 解释器将其视为
Where-Object <ScriptBlock> -and <ScriptBlock>
。由于 -and
运算符对布尔值进行操作,因此 PowerShell 将 ScriptBlocks 转换为布尔值。在 PowerShell 中,任何非空、零或 null 都是 true。然后该语句看起来像Where-Object $true -and $true
,这始终是正确的。
不要使用,而是使用括号
()
。
您还想使用 -eq
而不是 -match
,因为 match 使用正则表达式,如果在字符串中的任何位置找到该模式,则为 true(尝试:'xlsx' -match 'xls'
)。
Invoke-Command -computername SERVERNAME
Get-ChildItem -path E:\dfsroots\datastore2\public |
Where-Object ($_.extension -eq ".xls" -or $_.extension -eq ".xlk") -and ($_.creationtime -ge "06/01/2014")
更好的选择是在Get-ChildItem
命令中过滤扩展。
Invoke-Command -computername SERVERNAME
Get-ChildItem -path E:\dfsroots\datastore2\public\* -Include *.xls, *.xlk |
Where-Object $_.creationtime -ge "06/01/2014"
【讨论】:
括号没有解决问题,只是改变了结果,当我试图搜索的只是 xls 和 xlk 文件时,我得到的是 xlsx 文件。 查看我的编辑。-match
运算符将匹配字符串中的任何位置。【参考方案2】:
当你应该使用括号时,你使用了大括号。
where 语句保存在脚本块中,该脚本块使用弯曲的括号
定义。要隔离/包装您的测试,您应该使用括号 ()
。
我还建议尝试在远程计算机上进行过滤。试试:
Invoke-Command -computername SERVERNAME
Get-ChildItem -path E:\dfsroots\datastore2\public |
Where-Object ($_.extension -eq "xls" -or $_.extension -eq "xlk") -and $_.creationtime -ge "06/01/2014"
【讨论】:
括号没有解决问题,只是改变了结果,当我试图搜索的只是 xls 和 xlk 文件时,我得到的是 xlsx 文件。 您还使用了错误的运算符。很抱歉没有抓住那个。您需要使用-eq
来获得完全匹配。 -match
将包括所有扩展名包含短语“xls”的结果。 :)【参考方案3】:
我在这里找到了解决方案:
How to properly -filter multiple strings in a PowerShell copy script
Get-ChildItem
必须使用 -Include
标志
我的例子:
$Location = "C:\user\files"
$result = (Get-ChildItem $Location\* -Include *.png, *.gif, *.jpg)
别忘了在路径位置后加上“*”。
【讨论】:
以上是关于PowerShell Where-Object 语句中的多个 -and -or的主要内容,如果未能解决你的问题,请参考以下文章
如何像 IN 语句一样使用 Powershell Where-Object
PowerShell Where-Object 语句中的多个 -and -or
PowerShell Where-Object 筛选出包含指定内容的行