ferry
ferry

Reputation: 97

Search in/for text in files

I am currently learning LPTHW Ex 46. In his video tutorial, Zed had done the following commands:

  1. Find NAME within files using grep -r "NAME" *.

  2. Find all files with extension ending in .pyc using find . -name "*pyc" -print.

Unfortunately, the above code does not work on Windows PowerShell. May I know what their Windows PowerShell equivalents are?

Based on my search, item 1 can be replaced by Select-String. However, it is not as good as we can only search specific files and not directories. For example, while this would work:

Select-String C:\Users\KMF\Exercises\Projects\gesso\gesso\acrylic.py -pattern "NAME"

this would not:

Select-String C:\Users\KMF\Exercises\Projects\gesso -Pattern "NAME"

and it gives the following error

Select-String : The file C:\Users\KMF\Exercises\Projects\gesso can not be read: Access to the path 'C:\Users\KMF\Exercises\Projects\gesso' is denied.

For item 2 I could not find a similar function.

Upvotes: 0

Views: 92

Answers (1)

Ansgar Wiechers
Ansgar Wiechers

Reputation: 200193

grep and find are Unix/Linux shell commands. They won't work in PowerShell unless you install a Windows port of them.

As you already found out, Select-String is the PowerShell equivalent for grep. It doesn't recurse by itself, though, so you have to combine it with Get-ChildItem to emulate grep -r:

Get-ChildItem -Recurse | Select-String -Pattern 'NAME'

For emulating find you'd combine Get-ChildItem with a Where-Object filter:

Get-ChildItem -Recurse | Where-Object { $_.Extension -eq '.pyc' }

PowerShell cmdlets can be aliased to help administrators avoid extensive typing (since PowerShell statements tend to be rather verbose). There are several built-in aliases, e.g. ls or dir for Get-ChildItem, and ? or where for Where-Object. You can also define aliases of your own, e.g. New-Alias -Name grep -Value Select-String. Parameter names can be shortened as long as the truncated parameter name remains unique for the cmdlet. When cmdlets allow positional parameters they can even be omitted entirely.

With all of the above your two PowerShell statements can be reduced to the following:

ls -r | grep 'NAME'
ls -r | ? { $_.Extension -eq '.pyc' }

Note however, that aliases and abbreviations are mainly intended as an enhancement for console use. For PowerShell scripts you should always use the full form, not only for readability, but also because aliases may differ from environment to environment. You don't want your scripts to break just because they're run by someone else.

Upvotes: 1

Related Questions