Search code examples
powershellget-childitem

Powershell Get-ChildItem -Filter '*.txt' also finds '*.txt~' (too greedy?)


I'm on Windows 11 with Powershell vesrion 5.1.22621.963.

I want to list the contents of a directory while filtering on files ending in ".txt". I try the following:

> ls -Filter "*.txt"


    Directory: C:\so_example


Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-a----          3/3/2023  11:25 AM              0 example.txt
-a----          3/3/2023  11:25 AM              0 example.txt~

But that also finds files that end in ".txt~" with a tilde, '~', as the last character. Those are backup files added by my text editor. I can remove them, but it gets pretty tedious if I have a large directory with many backup files.

What's going on here? Why is the tilde being matched? How can I stop it from being matched?

I tried forming a search expression that will match only to the end of "txt", like this:

> ls -Filter "*.txt$"

But this returns no results (in the same directory as above).


Solution

  • This is an anomaly of the .NET API:

    When you use the asterisk wildcard character in searchPattern and you specify a three-character file extension, for example, "*.txt", this method also returns files with extensions that begin with the specified extension.

    There is a workaround, but it includes a limitation of the search string. If you don't use the start but instead a row of questions marks, you get the expected result:

    Get-Child-Item -Filter '??????????????????.txt'
    

    Limitation: If the number of ? is too small you get less file names.

    1https://learn.microsoft.com/en-us/dotnet/api/system.io.directory.enumeratefiles?view=net-7.0