How to Extract Lines Between Two Strings in PowerShell?

Recently, I received a requirement to extract lines of text between two specific strings from a log file. It is easy in PowerShell. In this tutorial, I will show you different methods to extract lines between two strings in PowerShell.

To extract lines between two strings in PowerShell, you can use the Select-String cmdlet with a regular expression. For example, to extract log entries between two dates, define the start and end dates, read the log file content using Get-Content, and apply Select-String with a pattern like (?s)$startDate.*?$endDate to match all text between the specified dates, including newlines.

Extract Lines Between Two Strings in PowerShell

There is no direct method available in PowerShell strings to do this, but you can try the methods below.

Let me show you one by one with examples.

Method 1: Using Regular Expressions

In PowerShell, you can use regular expressions to get lines between two strings. Let me show you an example.

Here, I have a log file that contains server logs. I will show you how to extract all entries between two specific dates using regular expressions in PowerShell.

Here is how you can do it:

# Define the start and end dates
$startDate = [datetime]::ParseExact("2024-07-01", "yyyy-MM-dd", $null)
$endDate = [datetime]::ParseExact("2024-07-15", "yyyy-MM-dd", $null)

# Read the log file
$logFile = "C:\MyNewFolder\server.log"
$logContent = Get-Content $logFile

# Initialize an array to store the extracted logs
$extractedLogs = @()

# Loop through each line in the log file
foreach ($line in $logContent) {
    # Extract the date from the log entry
    if ($line -match "^(?<date>\d{4}-\d{2}-\d{2})") {
        $logDate = [datetime]::ParseExact($matches['date'], "yyyy-MM-dd", $null)
        
        # Check if the log date is within the specified range
        if ($logDate -ge $startDate -and $logDate -le $endDate) {
            $extractedLogs += $line
        }
    }
}

# Output the extracted logs
$extractedLogs

I executed the above PowerShell script, and you can see the output in the screenshot below:

powershell get lines between two strings

Read Check if a String Contains Only Numbers in PowerShell

Method 2: Using Get-Content and Manual Parsing

Another approach is to manually read the file line by line and extract the lines between the two strings. This method gives more control over the extraction process.

Let me show you an example.

Suppose you have a configuration file, and you want to extract settings between two markers, [START_CONFIG] and [END_CONFIG]:

# Define the start and end markers
$startMarker = "[START_CONFIG]"
$endMarker = "[END_CONFIG]"

# Read the configuration file
$configFile = "C:\Configs\app.config"
$configContent = Get-Content $configFile

# Initialize variables
$inBlock = $false
$result = @()

# Loop through each line and extract lines between the markers
foreach ($line in $configContent) {
    if ($line -match $startMarker) {
        $inBlock = $true
        continue
    }
    if ($line -match $endMarker) {
        $inBlock = $false
        continue
    }
    if ($inBlock) {
        $result += $line
    }
}

# Output the extracted configuration settings
$result

In this example, we loop through each line of the configuration file and use flags to determine when to start and stop recording lines.

If you do not want to use a file here, you can take some hard-coded strings. Here is a complete script.

# Define the start and end markers
$startMarker = "[START_CONFIG]"
$endMarker = "[END_CONFIG]"

# Hard-coded configuration content
$configContent = @"
Some initial text
[START_CONFIG]
setting1=value1
setting2=value2
setting3=value3
[END_CONFIG]
Some final text
"@ -split "`n"

# Initialize variables
$inBlock = $false
$result = @()

# Loop through each line and extract lines between the markers
foreach ($line in $configContent) {
    if ($line -match [regex]::Escape($startMarker)) {
        $inBlock = $true
        continue
    }
    if ($line -match [regex]::Escape($endMarker)) {
        $inBlock = $false
        continue
    }
    if ($inBlock) {
        $result += $line
    }
}

# Output the extracted configuration settings
$result

You can see the output in the screenshot below after I executed the above script using VS code. The output is half visible as the screenshot becomes a little big.

Extract Lines Between Two Strings in PowerShell

Check out Convert String to Boolean in PowerShell

Method 3: Using StreamReader for Large Files

For very large files, reading the entire file into memory might not be efficient. Instead, you can use StreamReader to read the file line by line.

Let me show you an example of how to extract data from a large CSV file.

Suppose you have a large CSV file containing transaction data, and you need to extract transactions between two specific transaction IDs:

# Define the start and end transaction IDs
$startID = "TX12345"
$endID = "TX67890"

# Open the CSV file
$csvFile = "C:\MyNewFolder\transactions.csv"
$reader = [System.IO.StreamReader]::new($csvFile)

# Initialize variables
$inBlock = $false
$result = @()

# Read the file line by line
while ($reader.Peek() -ge 0) {
    $line = $reader.ReadLine()
    if ($line -match $startID) {
        $inBlock = $true
    }
    if ($inBlock) {
        $result += $line
    }
    if ($line -match $endID) {
        $inBlock = $false
    }
}

# Close the reader
$reader.Close()

# Output the extracted transactions
$result

In this example, we use StreamReader to efficiently read and process each line of the CSV file without loading the entire file into memory.

Conclusion

I hope now you know how to get lines between two strings in PowerShell. I have explained three methods with different examples.

You may like the following tutorials:

100 PowerShell cmdlets download free

100 POWERSHELL CMDLETS E-BOOK

FREE Download an eBook that contains 100 PowerShell cmdlets with complete script and examples.