How to Split Large Text Files with PowerShell (Lines, Size, CSV)

To split large text files with PowerShell, read the file in batches with Get-Content -ReadCount and write each batch to its own numbered file:

$part = 0
Get-Content -Path .\web-2026.log -ReadCount 100000 | ForEach-Object {
    $part++
    Set-Content -Path ('web-2026-part-{0:D3}.log' -f $part) -Value $_
}

Each pass of ForEach-Object gets an array of up to 100,000 lines, so the script never holds the whole file in memory. That’s the quick version.

Below I split a 500,000-line web server log (about 38 MB) by line count, by size in MB and at a marker line, split a CSV with its header in every part, and join the parts back with a hash check.

I timed each method in PowerShell 7.6 and Windows PowerShell 5.1, and the results weren’t what I expected. Encoding also changes the output files in 5.1, so there’s a section on that too.

Split a large text file by number of lines

The -ReadCount parameter sets how many lines Get-Content sends down the pipeline at a time. The default is 1. With 100000, $_ inside ForEach-Object is a whole chunk, and Set-Content writes it in one call:

$src = 'C:\psfaqs\t\splitfiles\web-2026.log'

$out = 'C:\psfaqs\t\splitfiles\parts'
$null = New-Item -ItemType Directory -Path $out -Force

$part = 0
Get-Content -Path $src -ReadCount 100000 | ForEach-Object {
    $part++
    $name = Join-Path $out ('web-2026-part-{0:D3}.log' -f $part)
    Set-Content -Path $name -Value $_
}

Get-ChildItem -Path $out | ForEach-Object {
    $lines = [Linq.Enumerable]::Count([IO.File]::ReadLines($_.FullName))
    '{0}  {1} lines  {2} MB' -f $_.Name, $lines, [math]::Round($_.Length / 1MB, 2)
}

Output:

web-2026-part-001.log  100000 lines  7.68 MB
web-2026-part-002.log  100000 lines  7.68 MB
web-2026-part-003.log  100000 lines  7.68 MB
web-2026-part-004.log  100000 lines  7.68 MB
web-2026-part-005.log  100000 lines  7.68 MB
PowerShell split large text file into 100,000-line parts with Get-Content -ReadCount
Five 100,000-line parts with numbered names (PowerShell 7)

The {0:D3} format pads the counter to three digits, so part-001 through part-005 sort in the right order in File Explorer and in Sort-Object. Use D4 if you expect more than 999 parts.

I counted the lines with [IO.File]::ReadLines, which streams the file instead of loading it. For other ways to check the totals, see counting lines in a file with PowerShell.

Split huge log files with StreamReader and StreamWriter

For multi-GB files, the classic advice is to skip the cmdlets and use the .NET StreamReader and StreamWriter classes. The reader returns one line at a time, and only the current line is in memory:

$src = 'C:\psfaqs\t\splitfiles\web-2026.log'

$out = 'C:\psfaqs\t\splitfiles\parts-stream'
$null = New-Item -ItemType Directory -Path $out -Force
$linesPerFile = 100000

$reader = [System.IO.StreamReader]::new($src)
$writer = $null; $part = 0; $count = 0
try {
    while ($null -ne ($line = $reader.ReadLine())) {
        if ($count % $linesPerFile -eq 0) {
            if ($writer) { $writer.Dispose() }
            $part++
            $name = Join-Path $out ('web-2026-part-{0:D3}.log' -f $part)
            $writer = [System.IO.StreamWriter]::new($name)
        }
        $writer.WriteLine($line)
        $count++
    }
} finally {
    if ($writer) { $writer.Dispose() }
    $reader.Dispose()
}
"Split $count lines into $part files"
(Get-ChildItem -Path $out).Name -join ', '

Output:

Split 500000 lines into 5 files
web-2026-part-001.log, web-2026-part-002.log, web-2026-part-003.log, web-2026-part-004.log, web-2026-part-005.log

The finally block closes the last writer and the reader even if the script fails halfway. StreamWriter writes UTF-8 without a BOM by default in both versions, which matters for the hash check later.

The same ReadLine loop is the basis of reading a file line by line in PowerShell, and it works well for filtering big log files before you split them.

Which method is fastest? Speed and memory tested