Reputation: 89
I have a variable $s that holds a filepath and an error based on piping a get-childitem to selecting a pattern in a string. the output looks something like this:
C:\Users\admin\Desktop\testpoint.txt:15906: Error: an error has been logged.
where
$s = C:\Users\admin\Desktop\testpoint.txt:15906: Error: an error has been logged.
Now what I want to do is select the string between \ and .txt (IE, the output in this example is testpoint) and output it as a secondary variable. 'regex::Matches' is what will allow me to do this from what I have researched, but the syntax is what is killing me. so far this is what i attempted:
[regex]::Matches($s, '\([^/)]+).txt')
but, it errors out. How do I go about getting whatever is between two constraints, in this case the constraints being the character " \ " and the string ".txt?"
Upvotes: 2
Views: 743
Reputation: 440162
An alternative is to use a single -replace
operation:
PS> $s = 'C:\Users\admin\Desktop\testpoint.txt:15906: Error: an error has been logged.'
$s -replace '^.+\\([^.]+)\..+$', '$1'
testpoint
But, as Mathias R. Jessen points out, it's probably easier to extract this information via properties from the Microsoft.PowerShell.Commands.MatchInfo
objects output by Select-String
, which your sample output suggests you're dealing with, along the lines of:
PS> Select-String -List 'Error:' *.log | Split-Path -LeafBase
testpoint
-List
limits the searches to at most 1 match per file.MatchInfo
output objects have a .Path
property reflecting the path of the file in which a match was found, and that property binds to Split-Path
's -Path
parameter via the pipeline.Note: The -LeafBase
parameter of the Split-Path
cmdlet requires PowerShell (Core) v7+, and isn't supported in Windows PowerShell; there you can use:
PS> Select-String -List 'Error:' *.log | ForEach-Object {
[IO.Path]::GetFileNameWithoutExtension($_.Path)
}
testpoint
Upvotes: 1
Reputation: 627409
You can use
[regex]::Match($s, '[^\\]+(?=\.txt)').value
The regex will match
[^\\]+
- one or more chars other than \
(?=\.txt)
- that are immediately followed with .txt
.See the .NET regex demo.
Another idea: cut at the second :
and parse the file name without extension:
[io.path]::GetFileNameWithoutExtension(($s -replace '^([^:]*:[^:]*):.*', '$1'))
See this regex demo. Details:
^
- start of string([^:]*:[^:]*)
- Group 1: zero or more chars other than :
, a :
, and again zero or more chars other than :
:
- a :
char.*
- the rest of the string.Upvotes: 2