How do I return only the matching regular expression when I select-string(grep) in PowerShell?

RegexPowershellGrep

Regex Problem Overview


I am trying to find a pattern in files. When I get a match using Select-String I do not want the entire line, I just want the part that matched.

Is there a parameter I can use to do this?

For example:

If I did

select-string .-.-.

and the file contained a line with:

abc 1-2-3 abc

I'd like to get a result of just 1-2-3 instead of the entire line getting returned.

I would like to know the Powershell equivalent of a grep -o

Regex Solutions


Solution 1 - Regex

Or just:

Select-String .-.-. .\test.txt -All | Select Matches

Solution 2 - Regex

David's on the right path. [regex] is a type accelerator for System.Text.RegularExpressions.Regex

[regex]$regex = '.-.-.'
$regex.Matches('abc 1-2-3 abc') | foreach-object {$_.Value}
$regex.Matches('abc 1-2-3 abc 4-5-6') | foreach-object {$_.Value}

You could wrap that in a function if that is too verbose.

Solution 3 - Regex

I tried other approach: Select-String returns property Matches that can be used. To get all the matches, you have to specify -AllMatches. Otherwise it returns only the first one.

My test file content:

test test1 alk atest2 asdflkj alj test3 test
test test3 test4
test2

The script:

select-string -Path c:\temp\select-string1.txt -Pattern 'test\d' -AllMatches | % { $_.Matches } | % { $_.Value }

returns

test1 #from line 1
test2 #from line 1
test3 #from line 1
test3 #from line 2
test4 #from line 2
test2 #from line 3

Select-String at technet.microsoft.com

Solution 4 - Regex

In the spirit of teach a man to fish ...

What you want to do is pipe the output of your select-string command into Get-member, so you can see what properties the objects have. Once you do that, you'll see "Matches" and you can select just that by piping your output to | **Select-Object** Matches.

My suggestion is to use something like: select linenumber, filename, matches

For example: on stej's sample:

sls .\test.txt -patt 'test\d' -All |select lineNumber,fileName,matches |ft -auto

LineNumber Filename Matches
---------- -------- -------
         1 test.txt {test1, test2, test3}
         2 test.txt {test3, test4}
         3 test.txt {test2}

Solution 5 - Regex

None of the above answers worked for me. The below did.

Get-Content -Path $pathToFile | Select-String -Pattern "'test\d'" | foreach {$_.Matches.Value}

Get-Content -Path $pathToFile | # Get-Content will divide into single lines for us

Select-String -Pattern "'test\d'" | # Define the Regex

foreach {$_.Matches.Value} # only return the value of the Object's Matches field. (This allows for multiple result matches.)

Solution 6 - Regex

Instead of piping to % or select you can use simpler .prop Member Enumeration syntax, which magically works on multiple elements:

(Select-String .-.-. .\test.txt -All).Matches.Value

or less parentheses:

$m = Select-String .-.-. .\test.txt -All
$m.Matches.Value

Solution 7 - Regex

You can use the System.Text.RegularExpressions namespace:

http://msdn.microsoft.com/en-us/library/system.text.regularexpressions.regex.aspx

Solution 8 - Regex

If you don't want to use ForEach operator, you can only use pipes and Select -Expand

For example, to get only the path after C:\, you could use :

Get-ChildItem | Select-String -Pattern "(C:\\)(.*)" | Select -Expand Matches | Select -Expand Groups | Where Name -eq 2 | Select -Expand Value

Where Name -eq 2 only selects the second match of the regex pattern specified.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionSkylerView Question on Stackoverflow
Solution 1 - RegexKeith HillView Answer on Stackoverflow
Solution 2 - RegexSteven MurawskiView Answer on Stackoverflow
Solution 3 - RegexstejView Answer on Stackoverflow
Solution 4 - RegexJaykulView Answer on Stackoverflow
Solution 5 - Regex7r4c0rView Answer on Stackoverflow
Solution 6 - RegexCarl WalshView Answer on Stackoverflow
Solution 7 - RegexDavid McEwingView Answer on Stackoverflow
Solution 8 - RegexAdrien ConstantView Answer on Stackoverflow