0

I'm trying to find a out when a series of values are present in a text file. Search value one will always be at least one line above search value two. However, it could be 20 lines down, or not exist at all.

Every version of regex I attempt returns a null value for the variable, because it's not present on both lines. I've attempted to use context, but that just brings back the records of a single search, I can't subsearch within them. I'd appreciate any assistance. Value 1 is "Check: All". Value 2 is "Net Totals"

$path = "C:\TEMP\generic.txt"

$try1 =  ( Get-Content $path | Out-String ).Trim() | select-string -Pattern "VALUE1:*.VALUE2 " -AllMatches |Select-Object -first 1 | Out-String 

$try2=  ( Get-Content $path -raw | Select-String -Pattern '(.*VALUE1\r\nVALUE2.*)' -AllMatches | select -expand Matches | select -expand Groups |  select -expand Value )#| Set-Content $outfile
freakostudent
  • 105
  • 1
  • 2
  • 9
  • 1
    When asking for regex help it is wise to include examples of the input and your desired output, it will help others understand what you're trying to accomplish. – Santiago Squarzon Jul 13 '21 at 23:49
  • What is the "result" you speak of storing? If it's the search terms, you already have those? What do you *expect* to end up with after finding some matches? The entire string from value1 to value2? – Doug Maurer Jul 14 '21 at 00:04
  • To make it easy, I'd like the entire plain text string of the found matches. If it finds 50, cool. If it finds 1, that's good too. from there I can substring what I want to make the results more polished. What really matters is I have to first find VALUE1, then find VALUE2. Both have to be present in that order. – freakostudent Jul 14 '21 at 00:15

1 Answers1

1

You need to treat it as a single string like you are doing, but then your pattern has to account for all characters between the two values. That could include multiple new line/carriage returns since the amount of lines vary.

You need a nongreedy match. Hopefully the following examples answer your question.

First, a sample file

$tempfile = New-TemporaryFile

@'
a line with value1 in it
some line
and another line
a line with value2 in it
a line
a line with value1 in it
some line
and another line
yet another line
a line with value2 in it
a line with value1 in it
some line
and another line
yet another line
too many lines
a line with value2 in it
'@ | Set-Content $tempfile

Using Select-String

$text = Get-Content $tempfile -Raw

$pattern = '(?s)(value1).+?(value2)'

($text | Select-String -Pattern $pattern -AllMatches).Matches|ForEach-Object {
    "----- This is one match -----"
    $_.value
}

Using .Net [regex]

$text = Get-Content $tempfile -Raw

$pattern = '(value1).+?(value2)'

[regex]::Matches($text,$pattern,16)|ForEach-Object {
    "----- This is one match -----"
    $_.value
}

Output for both

----- This is one match -----
value1 in it
some line
and another line
a line with value2
----- This is one match -----
value1 in it
some line
and another line
yet another line
a line with value2
----- This is one match -----
value1 in it
some line
and another line
yet another line
too many lines

Interestingly if you use [regex] and omit -Raw from Get-Content it will strip out the new line/carriage returns and give you the same text but in a single line.

----- This is one match -----
value1 in it some line and another line a line with value2
----- This is one match -----
value1 in it some line and another line yet another line a line with value2
----- This is one match -----
value1 in it some line and another line yet another line too many lines a line with value2
Doug Maurer
  • 8,090
  • 3
  • 12
  • 13