kate
kate

Reputation: 291

PowerShell: get data between two strings

I've got next data into variable $out (type is Object[]):

Success...
Go!
0:#217> trace && .quit
   0x000 Subline         : _OK
   0x008 Timed      : NO
   0x016 Check     : _OK
   0x022 Post       : 
   0x030 Offset         : None
   0x038 Hint     : False
   0x050 NextHint    : False
quit:

I need extract text between string 0:#217> trace && .quit and quit: I wrote:

[Regex]::Match($out, "(?<=.quit').+?(?=quit:)").Value

But this extracts required data into a line (type String), not a column (Object[]). How to fix this?

P.S. I solved the problem by myself as follows

([Regex]'(?is)(?:(?<=\.quit).+(?=quit:))').Match(($out -join "`n")).Value

But maybe there is more perfect way to do this?

Upvotes: 2

Views: 6511

Answers (5)

Mike Q
Mike Q

Reputation: 7327

The following is for very simple searches, get the string data between a starting string and ending string.

Upside: Very simplistic

Downside: Does poorly for data with multiple matches etc

Code

Function Get-StringBetweenStartEnd {
    Param($Text,$Start,$End)
    $Regex = [Regex]::new("(?<="+$Start+")(.*)(?="+$End+")")           
    $Match = $Regex.Match($String)           
    if($Match.Success) { Return $Match.Value}else{Return ""}
}

Example Usage

$String = "Test: disconnected: 10.10.10.1::59270 (VNC Viewer closed)"           
$Result = Get-StringBetweenStartEnd -Text $String -Start "nected:" -End "::"
$Result.Trim()

Output:

10.10.10.1

Upvotes: 1

kate
kate

Reputation: 291

Problem solved

([Regex]'\s+0x([^q]+)').Match(($out -join "`n")).Value

Upvotes: 1

TessellatingHeckler
TessellatingHeckler

Reputation: 29013

This might work, but it makes some assumptions:

$out -match '^ '
  1. $out is always a String[]. Force it with @($out) if it might be a single string.
  2. You are using PowerShell v4 or v5, so -operator will act as a filter on an array.
  3. Your example data is accurate, and all the lines you want start with a space, and all the other lines do not.

Upvotes: 0

TessellatingHeckler
TessellatingHeckler

Reputation: 29013

[Edit: this will work if $out is a String[], e.g. from $out = Get-Content results.txt, from your other comments, you might have something different].

As a general approach, have a true/false flag which chooses whether lines are allowed through or not, and when you see the first line then set the flag, and when you see the last line you want, change the flag.

$middle = foreach ($line in $out) {
    if ($line -match '^quit') { $allow = $false }
    if ($allow) { write-output $line }
    if ($line -match '0:#217>') { $allow = $true }
}

The ordering of the tests determines whether the start or end lines show up in the results or not.

This can be shortened on the console for typing, into something like:

#   loop  # end line clears flag       # print?     # start line sets flag
$out |% { if($_ -match '^quit'){$f=0}; if ($f){$_}; if ($_ -match '0:#217>'){$f=1} }

Upvotes: 0

Martin Brandl
Martin Brandl

Reputation: 58961

Just use the -split function to create a String[] of your result:

$result = ([regex]::Match($a, '\.quit(.*)quit:').Groups[1].value) -split [System.Environment]::NewLine

Upvotes: 0

Related Questions