问题
I want to get a list of files that don't have a filename extension. Consider the content of my directory to be:
folder
file1
file2.mp4
My goal would be to get file1
only.
Running Get-ChildItem -Exclude *.* -File
returned nothing.
Running Get-ChildItem -Exclude *.*
returned folder
and file1
.
Running Get-ChildItem -File
returned file1
and file2.mp4
.
Any idea if there is any way of using Get-ChildItem to only return file1
?
回答1:
In PSv3+, but doesn't work in PowerShell Core v6.x, fixed in v7 (see this GitHub issue):
Get-ChildItem -File -Filter *.
-File
limits output to just files (as opposed to directories).-Filter *.
selects only those files that have no extension.
-Filter
is generally preferable to -Include
/ -Exclude
for performance reasons, because it filters at the source, rather than returning all objects and letting PowerShell do the filtering.
In PSv2, where the -File
switch isn't available, you need an additional Where-Object
call to limit the results to files, as TheIncorrigible1 points out:
Get-ChildItem -Filter *. | Where-Object { -not $_.PSIsContainer }
Slower PowerShell Core solution:
Get-ChildItem -File | Where-Object -Not Extension
Optional background information:
That a -Filter
argument is processed by the underlying provider, not by PowerShell, means that its behavior may differ from PowerShell's, which is indeed the case here: the FileSystem provider uses the Windows API's wildcard-expression matching, which has fewer features than PowerShell's as well as some historical quirks; also, it is limited to a single wildcard expression, whereas -Include
/ -Exclude
support multiple ones (separated with ,
).
Here, however, -Filter
offers something that PowerShell's wildcard matching doesn't: using *.
to match files / directories without extension.
-Include
/ -Exclude
generally offer functional advantages at the expense of performance, but they have their own limitations and quirks:
*.
isn't supported to match items without extension in PowerShell's wildcard language, and there is no wildcard-based way to achieve this that I know of.-Include
/-Exclude
operate on the last component of the specified or implied path, so if you're implicitly targeting the current directory, they apply to that directory path, not to the individual files inside.- Specifying
-Recurse
changes that, but that searches the entire directory subtree. - While you should be able to add
-Depth 0
to limit matches to the immediate child items while still being able to apply-Include
/-Exclude
, this is broken as of Windows PowerShell v5.1: The-Depth
argument is ignored in this case.
This problem has been fixed in PowerShell Core, however.
- Specifying
In short: -Include
/ -Exclude
offer no solution here.
来源:https://stackoverflow.com/questions/51718098/how-do-i-use-get-childitem-to-return-files-that-dont-have-an-extension