Being GREP like on Windows
For many years I used grep on UNIX. It’s an amazing tool, allowing you to search for text in a variety of ways across a number of files. Windows however lagged behind and if you wanted to do the same thing, you needed a specialist program because that didn’t come baked into the operating system. At least, that was the case before PowerShell.
Here, I am going to illustrate how to use some of the PowerShell commands to imitate similar functionality on Windows whilst I hunt for errors in a log file (something I have needed to do, recently).
Let’s start with what we are searching through - here’s a small excerpt of the file I am using to give you an idea of what we will be finding. Bear in mind, however, that the real file is tens of thousands of lines long.
*INFO*: [soap/soapexe.c:4570] Built search: 0.312489 secs 0.000000 secs |
So where do we begin? Well, I want to know which lines contain the string “ERROR” (line 3) above and one way of achieving that is this command:
Select-String -Path .\stdout.txt ERROR |
That works well; we are searching in the file named “stdout.txt” for the string “ERROR”. Here you can see some of the results:
stdout.txt:50756:*ERROR*: [http-request.c:264] h_read failed (recv failed (No error)) |
Hold on, though. What about that last line? I don’t really want that, even though it does contain the desired string. Can you see the problem? It’s not being case-sensitive. To fix that, we can add another parameter.
Select-String -Path .\stdout.txt ERROR -CaseSensitive |
Ah, much better - we’ve gotten rid of that warning line.
stdout.txt:50756:*ERROR*: [http-request.c:264] h_read failed (recv failed (No error)) |
I did mention that there are a few less than a bazillion lines in this file? So really, I’d like to know which line number those matches occur on. “Select-String” is going to need some help, but the information is there, we just need to uncover it.
Select-String -Path .\stdout.txt ERROR -CaseSensitive | Select-Object -Property LineNumber |
Here, we’re piping the output to another command that is extracting particular properties, in this case, the line number. Run that, though, and you will see the following:
80624 |
And so on…(more ellipses!) That’s helpful, but really, the line number PLUS the actual line would be more useful. Only one more change to make:
Select-String -Path .\stdout.txt ERROR -CaseSensitive | Select-Object -Property LineNumber,Line |
Leading to:
292402 *ERROR*: [http-server.c:688] h_new_from_socket failed (recv failed (No error)) |
If you need to, you can find more information on the Select-String and Select-Object commandlets at the excellent MS docs website.
Happy searching.
Hi! Did you find this useful or interesting? I have an email list coming soon, but in the meantime, if you ready anything you fancy chatting about, I would love to hear from you. You can contact me here or at stephen ‘at’ logicalmoon.com