DEV Community

Cover image for How to "grep" in PowerShell
Antonin J. (they/them)
Antonin J. (they/them)

Posted on • Edited on • Originally published at antjanus.com

How to "grep" in PowerShell

PowerShell is awesome if you haven't used it but it's absolutely foreign if you're used to Unix-like Bash-like shells. For instance, there's no grep, and ls -al won't work (but ls will and it'll display all files with details!).

If you switch from Linux to Windows, you might be tempted to either install Cygwin or all of your GNU utilities. Or you might go the Linux subsystem route (which is a totally fair way to go) but if you want to go the PowerShell route, here's a neat little tip!

What's grep?

Grep is basically a utility that lets you filter some data using various patterns. There's a LOT more to it but my own common usage of it is:

$ cat .bash_history | grep ssh
ssh root@0.0.0.0
ssh deploy@0.0.0.0
ssh ubuntu@0.0.0.0
Enter fullscreen mode Exit fullscreen mode

This will filter out the output of cat and return only commands that include ssh. I use this to remind myself of IPs of servers I've recently used. Or I might do this:

$ cat package.json | grep webpack
    "start:dev": "webpack --config webpack/dev.config.js",
    "webpack": "3.8.1",
    "webpack-dev-server": "^2.9.4",
    "webpack-merge": "^4.1.1",
Enter fullscreen mode Exit fullscreen mode

to get all of my webpack plugins, scripts, and figure out the latest version of webpack. It's a handy utility, and I use it all the time. To filter lists of files in a folder and pipe them to another command or whatever else.

Grep is POWERFUL and it's super featureful but I won't get into that in this article.

So what does PowerShell have that's the equivalent?

Introducing Select-String

One thing that's immediately apparent about PowerShell is that its commands have better naming conventions. In fact, PS script is more like a programming language than Bash.

PowerShell piping is like Bash piping though it has some differences that I won't go into right now.

cat package.json | Select-String -Pattern webpack
ls ./src/components/ | Select-String -Pattern View
Enter fullscreen mode Exit fullscreen mode

Select-String supports regular expressions so you can also write more complicated stuff like:

C:\> cat post.md | Select-String -Pattern "^\w*:"

title: How to "grep" in PowerShell
published: false
description:
tags:

Enter fullscreen mode Exit fullscreen mode

This will extract the front-matter from this post (at the time of writing this section).

How about searching through multiple files?

Absolutely! Grep has a pretty easy syntax for it: grep $PATTERN glob/pattern/**. An -r flag will recursively search through a path.

You might use it to identify where you're using @select in your Angular application. @select is a decorator provided by the angular-redux store.

$ grep -r "@select" *.ts
comments-list.component.ts:  @select(['comments']) comments: Observable<IComment[]>;
comments-list.component.ts:  @select(authorsSelector) authors: Observable<any>;
comments-list.component.ts:  @select(['topComment']) topComment: Observable<IComment>;
Enter fullscreen mode Exit fullscreen mode

So what about PowerShell? In PowerShell, you have to specify an argument but the explicitness actually makes a lot of sense:

C:\> Select-String -Path *.ts -Pattern "@select"

comments-list.component.ts:51:  @select(['comments']) comments: Observable<IComment[]>;
comments-list.component.ts:53:  @select(authorsSelector) authors: Observable<any>;
comments-list.component.ts:55:  @select(['topComment']) topComment: Observable<IComment>;

Enter fullscreen mode Exit fullscreen mode

Cool, what about recursion? Err...well, to have true recursion working and scan "n" levels deep, you'll need to string a few commands together so we'll skip that for now.

Happy PowerShelling!

Advanced Examples

Before I leave, I'd like to impart some fun advanced commands. Like I said, PowerShell piping isn't like Linux piping. One of the big differences is that PowerShell utilizes "objects".

So here's a great example:

C:\> Select-String -Path *.ts -Pattern "@select" | Select Filename, LineNumber, Line, Path | Format-Table
Enter fullscreen mode Exit fullscreen mode

What this will do is: find files and matches to our pattern in all of TypeScript files in our current directory, select only the information we want to see, and transform it into a nice looking table like so (edited to fit site width):

Filename                    LineNumber   Line               Path
--------                    ----------   ----               ----
comments-list.component.ts  51           @select(['comme... C:\comments-list...
comments-list.component.ts  53           @select(authors... C:\comments-list...
comments-list.component.ts  55           @select(['topCo... C:\comments-list...
Enter fullscreen mode Exit fullscreen mode

You can then save it into a file via Out-File <filename> like so:

C:\> Select-String -Path *.ts -Pattern "@select" | Select Filename, LineNumber, Line, Path | Format-Table | Out-File selectors.txt
Enter fullscreen mode Exit fullscreen mode

Or output to a CSV:

C:\> Select-String -Path *.ts -Pattern "@select" | Select Filename, LineNumber, Line, Path | Format-Table | Export-Csv -path selectors.csv -NoTypeInformation
Enter fullscreen mode Exit fullscreen mode

What I love about PowerShell is that this stuff is built-in and it has sensible names. When I read bash scripts, it can be confusing. I mean, what does awk do? What about sed? Can you infer their jobs based on their names? Or what their flags mean?

Top comments (7)

Collapse
 
malikbenkirane profile image
Malik Benkirane

Hey !
But what about ag ?
I consider this is as a serious alternative
to unify these systems made by property guys.

Regards,
Malik

Collapse
 
malikbenkirane profile image
Malik Benkirane

I cannot argue there will always be many options. But then this is a mess. For example I like dwm, st, vim, unite.vim, goyo.vim, limelight.vim, gruvbox, xrdb all these good old tools together makes very appreciable desktop environments too...

Collapse
 
rubberduck profile image
Christopher McClellan

Tmux has basically become my desktop. I’m also using the Lynx text based browser, so I have no idea why I bother running an X server actually...

Thread Thread
 
malikbenkirane profile image
Malik Benkirane

Have you tried edbrowse yet ? 😌

Collapse
 
antjanus profile image
Antonin J. (they/them)

oh yeah, I LOVE Vim. And it works really well cross-platform, too. I did an article a while ago on VIM setup on Windows, I'd love to write a new one if people are interested in that.

Collapse
 
antjanus profile image
Antonin J. (they/them)

I wanted to mention what's built-in. There are obviously TONS of options, even cross-platform options that are good, too.

Collapse
 
shalvah profile image
Shalvah

Great article! I suggest you mention that cat in PowerShell is an alias for a more "sensible" command name (Get-Object, I think)