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

Time:01-12

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.

CodePudding user response:

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) }

CodePudding user response:

You are missing the -Name flag:

Get-ChildItem -Name | Select-String -Pattern "foo.sh"
  • Related