2

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?"

1
  • 3
    It's probably a better idea to fix the problem at its source, instead of using regex to extract the output from another regex operation. Get-ChildItem ... |Select-String -Pattern $pattern |ForEach-Object { (Get-Item -LiteralPath $_.Path).BaseName } would have given you just the matched file's name sans the extension Commented Apr 21, 2021 at 18:43

2 Answers 2

2

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.
Sign up to request clarification or add additional context in comments.

Comments

1

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.
  • The 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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.