Skip to content
SimpleTools24

How to Split a Large Text File Into Smaller Files

By SimpleTools24Published 3 min read

To split a large text file, use the split command on macOS or Linux (for example split -l 100000 big.log part_ for 100,000 lines per file), a short PowerShell script on Windows, or a few lines of Python on any system. Splitting by line count keeps every line intact; splitting by byte size can cut a line in half unless you use the line-aware options shown below.

Before you split, though, it's worth asking whether you need to. If you only want to read or share one section, extracting that range is faster and leaves the original untouched.

Split by Lines or by Size?

Splitting methods compared
MethodKeeps lines wholePredictable part sizeBest for
By line countYesNoLogs, CSV, anything processed line by line
By byte sizeNo (can cut lines)YesFitting upload or attachment limits with binary-safe joins
By size, line-awareYesApproximatelyText files that must stay under a size limit
By content (date, key)YesNoLogs grouped by day, CSV grouped by region

Splitting on macOS and Linux

By Number of Lines

bash
split -l 100000 big.log part_

This creates part_aa, part_ab, part_ac... each with 100,000 lines. Add -d for numeric suffixes and --additional-suffix to keep an extension (GNU split, standard on Linux):

bash
split -l 100000 -d --additional-suffix=.log big.log part_
# part_00.log, part_01.log, ...

macOS ships a BSD version of split without --additional-suffix; you can rename the parts afterwards, or install GNU coreutils and use gsplit.

By Size, Without Breaking Lines

bash
split -C 50M big.log part_

-C (GNU) puts as many complete lines as fit into each 50 MB part. Plain -b 50M splits at exactly 50 MB and may cut a line in two, which is fine for binary files you'll rejoin but bad for logs you'll read.

Into a Fixed Number of Parts

bash
split -n l/4 big.log part_

This divides the file into four parts without splitting lines (GNU only).

Splitting a CSV and Keeping the Header

If you split a CSV with split -l, only the first part gets the header row. To repeat it in every part:

bash
tail -n +2 data.csv | split -l 500000 - chunk_
for f in chunk_*; do
  (head -n 1 data.csv; cat "$f") > "$f.csv" && rm "$f"
done

The first line takes everything except the header and splits it; the loop puts the header back on top of each chunk. Watch out for CSV fields containing line breaks, as covered in how to open large CSV files: line-based splitting can separate them.

Splitting on Windows With PowerShell

PowerShell can stream a file line by line and write parts as it goes. This version handles large files without loading them into memory:

powershell
$src = "C:\logs\big.log"; $lines = 100000; $i = 0; $part = 0
$reader = [System.IO.File]::OpenText($src)
$writer = $null
while (($line = $reader.ReadLine()) -ne $null) {
  if ($i % $lines -eq 0) {
    if ($writer) { $writer.Close() }
    $part++
    $writer = [System.IO.StreamWriter]::new("C:\logs\big_part$part.log")
  }
  $writer.WriteLine($line); $i++
}
if ($writer) { $writer.Close() }
$reader.Close()

Avoid Get-Content big.log | ... with very large files when speed matters; it works but is much slower than the stream reader. Note that this script writes UTF-8 output, which may differ from the original file's encoding.

Splitting With Python (Any Platform)

python
lines_per_part = 100_000
part, out = 0, None
with open("big.log", "r", encoding="utf-8", errors="replace") as src:
    for n, line in enumerate(src):
        if n % lines_per_part == 0:
            if out:
                out.close()
            part += 1
            out = open(f"big_part{part:03}.log", "w", encoding="utf-8")
        out.write(line)
if out:
    out.close()

Python reads the file line by line, so memory use stays low regardless of size.

Splitting by Content

Sometimes the natural split is by date or category rather than size. For logs with an ISO date at the start of each line:

bash
awk '{ print > ("app-" substr($1, 1, 10) ".log") }' app.log

Each line goes into a file named after its date, such as app-2026-10-07.log. Make sure the first field really is the date before running this.

Joining the Parts Back Together

bash
cat part_* > rejoined.log            # macOS / Linux
bat
copy /b part_aa + part_ab + part_ac rejoined.log

Shell globs sort alphabetically, which matches the order split used. For CSV parts with repeated headers, remove the extra header lines when joining.

Do You Need to Split at All?

Splitting is often a workaround for an editor that can't open the file. If the goal is reading, searching or sharing a portion, alternatives are simpler:

  • Search instead. Find the lines you need with grep; see how to search large log files.
  • Extract a range. sed -n '200000,250000p' big.log > excerpt.log copies just those lines.
  • Use a viewer. A large file viewer lets you jump to any line and export a range of lines as a smaller download, with no splitting and no command line.

Frequently Asked Questions

Will splitting change the file's content?

Splitting by lines or bytes doesn't modify data; rejoining the parts in order recreates the original exactly. Scripts that rewrite text can change line endings or encoding, so compare checksums if that matters.

How many lines should each part have?

It depends on the destination. For Excel, stay below 1,048,576 rows including the header. For email or uploads, split by size instead.

Why are my split parts slightly different sizes?

Line-based splitting gives each part the same number of lines, but lines vary in length, so byte sizes differ.

Can I split a gzipped log without decompressing it to disk?

Yes: zcat app.log.gz | split -l 100000 - part_ decompresses on the fly and splits the stream.

Summary

Use split -l or split -C on macOS and Linux, a stream-reading PowerShell or Python script on Windows, and remember to repeat CSV headers. If you only need part of the file, extract that range instead of splitting the whole thing.

Sources