powershellfile-listing

How to make a `ls | greep foo` with powershell?


I am doing a PowerShell script, I want to show at the terminal a list of the files like I do in bash: ls | grep "foo.sh"

I tried to make:

dir | select-string -pattern "foo.sh"

but that looks inside the files, I want to filter by the name. I also tried

get-childItem | select-string -pattern "foo.sh"

but I have the same problem. Text-Path isn't working because I need a list of the files.


Solution

  • In bash you should never pipe ls output to other commands, and the same applies to PowerShell in this case1. Even worse, since PowerShell cmdlets return objects, not strings, piping Get-ChildItem output to Select-String makes absolutely zero sense because the object needs to be converted to string somehow, which may not return a useful string to match

    The -Path parameter in Get-ChildItem already receives a pattern, just use it. That means to get the list of files whose names contain foo.sh just run

    Get-ChildItem -Path *foo.sh*
    

    or

    ls *foo.sh*
    

    In bash you do the same, and ls *foo.sh* returns more correct results than ls | grep foo.sh, and also faster. For listing foo.sh only obviously you just do ls foo.sh in both bash and PowerShell

    For better performance in PowerShell you can also use

    Get-ChildItem -Filter *foo.sh*
    

    which filters out names right from the Provider level, which calls the Win32 API directly with the pattern


    1Unlike bash, in PowerShell due to the object-oriented nature, sometimes you do pipe ls outputs to other commands for further processing, because you can operate on the original objects instead of strings so it'll still work for any files with special names or properties. For example

    Get-ChildItem | Where-Object { $_.Parent -eq "abc" -and $_.LastWriteTime -lt (Get-Date) }