Powershell Get-ChildItem -Filter operates differently to Where clause with same value

江枫思渺然 提交于 2019-11-27 04:50:22

问题


I have a folder on a server called MyFolder. There are additional folders called MyFolder.1, MyFolder.2, MyFolder.3 etc.

If I run:

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

I get the expected output:

    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  

However if I run:

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

I get:

    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                                                                

I'm confused on how MyFolder is included in the output. I'd expect the output to be the same.

The online help highlights that the syntax of the filter is based on the provider but I'm unsure what provider is being used in this instance.

Am I missing a fundamental piece of knowledge here? I've attempted to pass a regex string in to the filter e.g "MyFolder\.*" but this simply returns nothing. I'm sure I'm missing something simple.

I'm running Powershell version 2.

Resolution

Thanks to Roman Kuzmin for pointing out the differences in wildcard matching. The following gives the expected output:

gci C:\Sample\MyFolder.*

I'll be using this syntax for ease in the future to reduce noise in code.


回答1:


The Filter of FileSystem provider rather uses CMD wildcards than PowerShell wildcards. CMD wildcards are funny and not intuitive in some edge cases, mostly historically. Here is an interesting explanation: http://blogs.msdn.com/b/oldnewthing/archive/2007/12/17/6785519.aspx

Another gotcha to be kept in mind: ls -Filter *.txt in fact gets files like *.txt* in PowerShell sense, i.e. files with extensions starting with txt. This may be unexpected and very unpleasant in some scenarios :)




回答2:


gci C:\Sample -Filter "MyFolder.*"  # here is a filesystem provider; use wildcard `*`,`?`

return the same output as (in a cmd.exe shell):

dir Myfolder.* 

If you need a regex this is the way ( -filter doesn't accept regex)

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

like here

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

the comparison in the scriptblock is between [string] type.



来源:https://stackoverflow.com/questions/12913734/powershell-get-childitem-filter-operates-differently-to-where-clause-with-same

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!