I’m searching for the string “schedule” and once found, count the number of lines after it and before the next match. End result would something like this:
That way, I can sort the above array by Count and select the schedule with the lowest number. Any pointers in the right direction would be much appreciated.
There are going to be several ways to do it. If you can fit all the text in memory I would suggest this approach.
You bring all the content into memory as a single string with the -Raw parameter. I’ve commented the code to explain each step.
$content = Get-Content -Path \path\to\content.txt -Raw
# split on a non capturing match for literal string 'Schedule' sending each section as a single line of text
$content -split '(?=Schedule)' | ForEach-Object {
# split the single line at the newline/carriage return turning it into an array of lines
foreach($line in $_ -split '\r?\n'){
# if the current line matches 'schedule<space><0 or more numeric digits>' create the object
if($line -match '(Schedule \d*)'){
$current = [PSCustomObject]@{
Name = $matches.1
Count = 0
}
}
# otherwise if the line isn't just an empty line, increment the count
elseif($line -match '\w.+'){
$current.Count++
}
}
# implicit output since we done with this section
$current
# clear variable for next chunk
$current = $null
}
to capture it to a variable just put the variable assignment in front of the foreach loop
$content = Get-Content -Path \path\to\content.txt -Raw
# split on a non capturing match for literal string 'Schedule' sending each section as a single line of text
$output = $content -split '(?=Schedule)' | ForEach-Object {
# split the single line at the newline/carriage return turning it into an array of lines
foreach($line in $_ -split '\r?\n'){
# if the current line matches 'schedule<space><0 or more numeric digits>' create the object
if($line -match '(Schedule \d*)'){
$current = [PSCustomObject]@{
Name = $matches.1
Count = 0
}
}
# otherwise if the line isn't just an empty line, increment the count
elseif($line -match '\w.+'){
$current.Count++
}
}
# implicit output since we done with this section
$current
# clear variable for next chunk
$current = $null
}
# implicit output of the collected objects
$output
The question mark right after a pattern/literal makes it optional. This is the best approach tha I know of to match both new line and carriage return, as well as both.
The question mark as part of (?=…) is a look ahead pattern.
The dot means march any character, combined with + it means match one or more of any character. So it’s a letter \w plus one or more of any character .+