【问题标题】:Powershell Get-ChildItem -Filter operates differently to Where clause with same valuePowershell Get-ChildItem -Filter 与具有相同值的 Where 子句的操作方式不同
【发布时间】:2012-10-16 11:29:55
【问题描述】:

我在名为 MyFolder 的服务器上有一个文件夹。还有其他文件夹称为 MyFolder.1、MyFolder.2、MyFolder.3 等。

如果我跑:

gci C:\Sample | ? { $_.Name -like "MyFolder.*" }

我得到了预期的输出:

    Directory: C:\Sample


Mode                LastWriteTime     Length Name                                                                      
----                -------------     ------ ----                                                                      
d----        16/10/2012     12:16            MyFolder.1                                                                
d----        16/10/2012     12:16            MyFolder.2                                                                
d----        16/10/2012     12:16            MyFolder.3  

但是,如果我运行:

gci C:\Sample -Filter "MyFolder.*"

我明白了:

    Directory: C:\Sample


Mode                LastWriteTime     Length Name                                                                      
----                -------------     ------ ----                                                                      
d----        16/10/2012     12:16            MyFolder                                                                  
d----        16/10/2012     12:16            MyFolder.1                                                                
d----        16/10/2012     12:16            MyFolder.2                                                                
d----        16/10/2012     12:16            MyFolder.3                                                                

我对输出中如何包含 MyFolder 感到困惑。我希望输出是一样的。

online help 强调过滤器的语法基于提供程序,但我不确定在此实例中使用的是哪个提供程序。

我在这里缺少基本知识吗?我试图将一个正则表达式字符串传递给过滤器,例如"MyFolder\.*",但这根本不返回任何内容。我确定我错过了一些简单的东西。

我正在运行 Powershell 版本 2。

分辨率

感谢 Roman Kuzmin 指出通配符匹配的差异。以下给出了预期的输出:

gci C:\Sample\MyFolder.*

我将来会使用这种语法来减少代码中的噪音。

【问题讨论】:

  • 如果 Microsoft 更新帮助以解释 -Filter 对文件系统提供程序的作用,那就太好了,因为这可能是人们使用 Get-ChildItem 的 99.9% 最常见的情况。 “语法基于提供者”似乎有点虚伪。

标签: powershell filter get-childitem


【解决方案1】:

文件系统提供程序的Filter 使用 CMD 通配符而不是 PowerShell 通配符。 CMD 通配符在某些边缘情况下很有趣且不直观,主要是在历史上。这是一个有趣的解释:https://devblogs.microsoft.com/oldnewthing/20071217-00/?p=24143

另一个需要牢记的问题:ls -Filter *.txt 实际上在 PowerShell 中获取类似于 *.txt* 的文件,即具有txt开始扩展名的文件。在某些情况下,这可能是出乎意料且非常不愉快的:)

【讨论】:

  • 感谢您提供链接并突出显示通配符差异。这有助于我解决问题(但不是以我预期的方式......)
  • 关于-Filter *.txt 表现得像-Filter *.txt* 的优点。一个小问题:链接的文章谈论的是 MS-DOS,而不是 CMD (cmd.exe)。文章接着说(强调添加),“但是FCB 匹配算法的一些 怪癖仍然存在于Win32 中,因为它们已成为惯用语。”。换句话说,Windows API 提供了当前行为,详见this answer
  • 当文件夹中的一个脚本被命名为 filename.sql-skip 时,我可以保证使用 -Filter 并针对数据库运行一组 SQL 脚本会产生“意外和不愉快”的效果。
【解决方案2】:
gci C:\Sample -Filter "MyFolder.*"  # here is a filesystem provider; use wildcard `*`,`?`

返回与(在 cmd.exe shell 中)相同的输出:

dir Myfolder.* 

如果您需要正则表达式,这就是方法(-filter 不接受正则表达式)

gci C:\Sample | ? { $_.Name -match '^MyFolder\..*' }

喜欢这里

gci C:\Sample | ? { $_.Name -like "MyFolder.*" }

脚本块中的比较在[string]类型之间。

【讨论】:

  • 感谢 Christian,在重新阅读在线文档后不久,我意识到 Filter 不会采用正则表达式。
猜你喜欢
  • 2019-02-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-14
  • 2018-02-21
  • 1970-01-01
  • 1970-01-01
  • 2017-05-20
相关资源
最近更新 更多