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.

1 Answer 1

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

Sign up to request clarification or add additional context in comments.

2 Comments

mklement0 Thank you very much for your great solution. Exactly what I need. Great!
Glad to hear it, @Harpalyke; my pleasure. Since it sounds like the answer solved your problem, please don't forget to accept it.

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.