1

Old thread

My question regards:

function GetStringBetweenTwoStrings($firstString, $secondString, $importPath){

    #Get content from file
    $file = Get-Content $importPath

    #Regex pattern to compare two strings
    $pattern = "$firstString(.*?)$secondString"

    #Perform the opperation
    $result = [regex]::Match($file,$pattern).Groups[1].Value

    #Return result
    return $result

}
GetStringBetweenTwoStrings -firstString "Lorem" -secondString "is" -importPath "C:\Temp\test.txt"

This is nice for only one -firstString and -secondString, but how to use this function to chronologically write multiple same strings in numbered TXT?

txt - file(with more sections of text):
Lorem
....
is
--> write to 001.txt
Lorem
....
is
--> write to 002.txt
and so forth.... 

And the structure of the section is preserved and is not in one line.

I hope someone can tell me that. Thanks.

mklement0
  • 382,024
  • 64
  • 607
  • 775
Harpalyke
  • 33
  • 2

1 Answers1

1

The function you quote has several limitations (I've left feedback on the original answer), most notably only ever reporting one match.

Assuming an improved function named Select-StringBetween (see source code below), you can solve your problem as follows:

$index = @{ value = 0 }
Get-ChildItem C:\Temp\test.txt |
  Select-StringBetween -Pattern 'Lorem', 'is' -Inclusive |
  Set-Content -LiteralPath { '{0:000}.txt' -f ++$index.Value }

Select-StringBetween source code:

Note: The syntax is in part patterned after Select-String. After defining the function, run Select-StringBetween -? to see its syntax; the parameter names are hopefully self-explanatory.

function Select-StringBetween {
  [CmdletBinding(DefaultParameterSetName='String')]
  param(
    [Parameter(Mandatory, Position=0)]
    [ValidateCount(2, 2)] 
    [string[]] $Patterns,
    [Parameter(Mandatory, ValueFromPipelineByPropertyName, ParameterSetName='File')]
    [Alias('PSPath')]
    [string] $LiteralPath,
    [Parameter(Mandatory, ValueFromPipeline, ParameterSetName='String')]
    [string] $InputObject,
    [switch] $Inclusive,
    [switch] $SimpleMatch,
    [switch] $Trim
  )
  
  process {

    if ($LiteralPath) {
      $InputObject = Get-Content -ErrorAction Stop -Raw -LiteralPath $LiteralPath
    }
  
    if ($Inclusive) {
      $regex = '(?s)(?:{0}).*?(?:{1})' -f 
                  ($Patterns[0], [regex]::Escape($Patterns[0]))[$SimpleMatch.IsPresent],
                  ($Patterns[1], [regex]::Escape($Patterns[1]))[$SimpleMatch.IsPresent]
    }
    else {
      $regex = '(?s)(?<={0}).*?(?={1})' -f 
                  ($Patterns[0], [regex]::Escape($Patterns[0]))[$SimpleMatch.IsPresent],
                  ($Patterns[1], [regex]::Escape($Patterns[1]))[$SimpleMatch.IsPresent]
    }
    
    if ($Trim) {
      [regex]::Matches(
        $InputObject,
        $regex
      ).Value.Trim()
    }
    else {
      [regex]::Matches(
        $InputObject,
        $regex
      ).Value
    }
  }

}

Note that there's also a pending feature request on GitHub to add this functionality directly to Select-String - see GitHub issue #15136

mklement0
  • 382,024
  • 64
  • 607
  • 775
  • mklement0 Thank you very much for your great solution. Exactly what I need. Great! – Harpalyke Nov 17 '22 at 03:25
  • Glad to hear it, @Harpalyke; my pleasure. Since it sounds like the answer solved your problem, please don't forget to accept it. – mklement0 Nov 17 '22 at 04:00