Using Get-ChildItem -Exclude or -Include returns nothing

南楼画角 提交于 2019-11-27 04:41:06

问题


I have a list in my C: directory that has many files. If I try to run an -Exclude on it, I get no returns. Same with -Include. If I use filter it returns what I expected to get back. Am I not understanding what it should be doing?

Here is an example of what I am running and getting nothing:

Get-ChildItem -Path C: -Exclude "*.txt"

I get nothing back. If I run

Get-Childitem -filter "*.txt"

I get this back:

  Mode                LastWriteTime         Length Name                                                                               
----                -------------         ------ ----                                                                               
-a----        11/7/2007   8:00 AM          17734 eula.1028.txt                                                                      
-a----        11/7/2007   8:00 AM          17734 eula.1031.txt                                                                      
-a----        11/7/2007   8:00 AM          10134 eula.1033.txt                                                                      
-a----        11/7/2007   8:00 AM          17734 eula.1036.txt                                                                      
-a----        11/7/2007   8:00 AM          17734 eula.1040.txt                                                                      
-a----        11/7/2007   8:00 AM            118 eula.1041.txt                                                                      
-a----        11/7/2007   8:00 AM          17734 eula.1042.txt                                                                      
-a----        11/7/2007   8:00 AM          17734 eula.2052.txt                                                                      
-a----        11/7/2007   8:00 AM          17734 eula.3082.txt                                                                      
               7/7/2016   8:50 AM             93 HaxLogs.txt                                                                        
-a----         7/8/2016   8:30 AM              0 Test.txt 

回答1:


Get-ChildItem -Path "C:\*" -Include "*.txt"

This example, of how -Include should work, will give you the results you were expecting. Note that I provided a wildcard in the path parameter as well, to explicitly define the path as "any file in the root C:" as opposed to "C:" itself.

Source: https://technet.microsoft.com/library/hh849800.aspx

Example 3 from this link, in case it goes defunct (note the wildcard in path here, as well):

C:\> Get-ChildItem –Path "C:\Windows\Logs\*" -Include "*.txt" -Exclude "A*"



回答2:


To summarize and complement gravity's and Brian Reynolds's helpful answers:

There are two distinct problems with your approach:

  • Targeting C: probably doesn't (always) do what you want, because C: refers to whatever happens to be the current location (working dir.) on drive C: at the moment.

    • To target the root folder of drive C:, you must use C:\, which I'll assume is what you meant in the remainder of this answer.
  • Using the -Exclude (and also -Include) parameter with neither -Recurse nor a -Path value ending in \* often yields NO results. Unexpected? Indeed - see below for more.

    • Thus, Get-Item -Path C:\* -Exclude *.txt - note the switch from Get-ChildItem to Get-Item and the * after C:\ - is needed to make your command work for the items located directly in C:\ only.

Background information:

Using the provider-native -Filter parameter is generally preferable to -Include, because:

  • it is much faster than -Include due to the provider itself performing the filtering at the source, as opposed to letting PowerShell apply the filter later, after all objects have been received.

  • it doesn't require you to switch to Get-Item and append \* to the -Path parameter value.

    • Get-ChildItem -Path C:\ -Filter *.txt works fine for matching all *.txt files in the root directory of C:, for instance.

That said, there are Caveats:

  • The wildcard pattern language supported by -Filter has fewer features than PowerShell's and may unexpectedly match short (8.3) filenames - see this well-researched answer for the gory details.

  • -Filter supports only a single pattern, whereas -Include supports multiple ones (an array of patterns).

Unfortunately, -Filter is always a positive (inclusionary) filter and therefore cannot be used to provide the functionality of -Exclude.


The implementation of -Include / -Exclude with Get-ChildItem is unintuitive and has pitfalls:

Side note: if you only use one -Include pattern (as opposed to -Exclude), it's easier to append the pattern directly to the -Path argument; e.g.: Get-ChildItem C:\*.txt

tl;dr: To get predictable behavior with -Include / -Exclude, use Get-Item C:\path\to\* (note the appended \* and the switch from Get-*Child*Item) - unless you also use -Recurse.

  • -Include and -Exclude do not work as one would intuitively expect:

    • -Include and -Exclude modify the leaf (last) path component of the -Path argument.

    • That means that the patterns are applied to the leaf component of the folder path itself first, before getting applied to the child items, if at all.

    • If the input path doesn't end in \* and -Recurse is not specified, the implications are as follows:

      • -Include: If the input path's last path component does not match the -Include pattern(s), the input path itself is excluded (not included), and the path's child items are never looked at - nothing is output.

      • -Exclude: Analogously, if the input path's last path component does match the -Exclude pattern(s), the input path itself is excluded, and the path's child items are never looked at - nothing is output.

        • In the special case of path C:\ (Get-ChildItem -Path C:\ -Exclude <any-pattern>), where arguably the last path component is the empty string, it seems that any exclusion pattern is considered a match, and no output is ever produced.
    • As stated, the problem doesn't surface if -Recurse is used, because that forces descending into the input path's subtree, even if the input path itself is not included / excluded.

  • Unless -Recurse is needed, the only way to get expected behavior is to replace
    Get-ChildItem C:\path\to -Include / -Exclude with
    Get-Item C:\path\to\* -Include / -Exclude - note the use of Get-Item instead of Get-ChildItem, and that \* was appended to the -Path argument.

    • By contrast, if you use Get-ChildItem and there are directories among the matches, Get-ChildItem will output their contents instead.
  • With -LiteralPath rather than -Path, -Include and -Exclude are quietly ignored - they have no effect whatsoever.


Examples: problematic uses of -Include / -Exclude

Note: To make all commands below work as one would intuitively expect, replace Get-ChildItem C:\Windows with Get-Item C:\Windows\* - note the use of a different cmdlet, Get-Item, and the appended \*.

# HAPPENS TO WORK, BUT IS NOT ROBUST:
# Matches all w* items *inside* C:\Windows, but
# ONLY because w* happens to match 'Windows' - the last input
# path component - too.
Get-ChildItem C:\Windows -Include w*

# HAPPENS TO WORK, BUT IS NOT ROBUST:
# Matches all items whose names *don't* start with a-v *inside* C:\Windows, but
# ONLY because [a-v]* happens not to exclude 'Windows' - the last input
# path component - too.
Get-ChildItem C:\Windows -Exclude [a-v]*


# OUTPUTS NOTHING:
# Because t* doesn't match 'Windows', the child items of 
# 'C:\Windows' are not considered.
Get-ChildItem C:\Windows -Include t*

# OUTPUTS NOTHING:
# Because w* matches 'Windows', it is excluded, and
# the child items of 'C:\Windows' are not considered.     
Get-ChildItem C:\Windows -Exclude w*



回答3:


Using 'C:' with no slash after it is the reason you're not getting the results you want. This is being interpreted as a relative path to the current directory instead of the root of the C drive. (See: Path with no slash after drive letter and colon - what does it point to?)

If you use 'C:\' instead it should work as expected.

Edit: My mistake; I was responding specifically to the examples which only use '-exclude'.



来源:https://stackoverflow.com/questions/38269209/using-get-childitem-exclude-or-include-returns-nothing

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