csplit Command in Linux: Split Files by Pattern or Line Number

Tested on Ubuntu 25.04 (Plucky Puffin)
Package uutils-coreutils
csplit (uutils coreutils) 0.2.2
Applies to Ubuntu, Debian, RHEL, Rocky Linux, AlmaLinux, Oracle Linux, CentOS Stream, Fedora, Arch Linux, SUSE, openSUSE, Alpine
Privilege sudo or root
Man page csplit(1)
Scope The csplit command splits a text file into pieces at regex patterns or line numbers. Use it when file structure — headers, sections, markers — defines where to cut.
Related guides awk command cheat sheet
grep
cat
Linux commands

csplit — quick reference

Pattern-based splits

Cut the file at lines matching a regular expression. Wrap the pattern in / delimiters.

When to use Command
Split at every line matching PATTERN csplit FILE '/PATTERN/' '{*}'
Split only the first N matches csplit FILE '/PATTERN/' '{N}'
Omit the delimiter line from output pieces csplit --suppress-matched FILE '/PATTERN/' '{*}'

Line-number splits

Cut after absolute line numbers in the file (1-based).

When to use Command
Split after line 100 csplit FILE 100
Split after several line numbers csplit FILE 100 200 300

Output naming

Default output files are xx00, xx01, … with byte counts printed to stdout.

When to use Command
Custom filename prefix (-f) csplit -f part FILE '/PATTERN/' '{*}'
Custom suffix format (-b, sprintf style) csplit -f part -b '%02d.txt' FILE '/PATTERN/' '{*}'
More than two digits in numeric suffix (-n) csplit -n 3 FILE '/PATTERN/' '{*}'

Behaviour modifiers

When to use Command
Quiet mode — hide byte-count lines (-q) csplit -q FILE '/PATTERN/' '{*}'
Delete zero-byte output files (-z) csplit -z FILE '/PATTERN/' '{*}'
Keep partial output if csplit errors (-k) csplit -k FILE 99999

Rejoin and inspect

When to use Command
Concatenate pieces back in order cat xx* > restored.txt
List pieces and sizes after a split ls -l xx*

Help and version

When to use Command
Show brief usage csplit --help
Show package version csplit --version

csplit — command syntax

Synopsis from csplit --help on Ubuntu 25.04 (csplit uutils coreutils 0.2.2):

text
csplit [OPTION]... FILE PATTERN...

Each PATTERN is a line number (integer) or a regular expression wrapped in / characters. Repeat counts look like {3} (exactly three more splits) or {*} (as many as possible). Output defaults to xx00, xx01, … in the current directory.


csplit — command examples

Essential Split on a regex marker with {*}

Use csplit when a text file has repeated section headers — log blocks, report sections, or XML-like markers — and you want each block in its own file.

Create a sample file and split on SECTION:

bash
mkdir -p /tmp/csplit-lab && cd /tmp/csplit-lab
cat > report.txt << 'EOF'
HEADER LINE
line one
line two
SECTION
data a
data b
SECTION
data c
FOOTER
end
EOF
csplit report.txt '/SECTION/' '{*}'

Sample output (byte counts on stdout):

text
30
22
26

List the pieces:

bash
ls -l xx*

Sample output:

output
-rw-r--r-- 1 root root 30 Jul  1 17:51 xx00
-rw-r--r-- 1 root root 22 Jul  1 17:51 xx01
-rw-r--r-- 1 root root 26 Jul  1 17:51 xx02

xx00 holds lines before the first SECTION; later files hold content starting at each match through the next split.

Essential Split at fixed line numbers

When you know exact line boundaries — for example "first 3 lines are header" — pass line numbers instead of regex patterns.

Run the command:

bash
cd /tmp/csplit-lab
rm -f xx*
csplit report.txt 3 6

Sample output:

output
21
24
33

Inspect the first piece:

bash
cat xx00

Sample output:

output
HEADER LINE
line one
line two

xx01 contains lines 4–6; xx02 is the remainder of the file.

Common Custom output names with -f and -b

Default xx00 names are fine for quick work. In scripts, -f sets the prefix and -b sets a sprintf-style suffix.

Run the command:

bash
cd /tmp/csplit-lab
rm -f part*
csplit -f part -b '%02d.txt' report.txt '/SECTION/' '{*}'

Sample output:

output
30
22
26

List results:

bash
ls part*

Sample output:

output
part00.txt
part01.txt
part02.txt

Sorted names make reassembly and downstream tools easier.

Common Drop delimiter lines from output

By default, the matching SECTION line stays in the output piece. --suppress-matched removes those delimiter lines from every file.

Run the command:

bash
cd /tmp/csplit-lab
rm -f xx*
csplit --suppress-matched report.txt '/SECTION/' '{*}'
cat xx01

Sample output from xx01:

text
data a
data b

Compare with the plain split where xx01 still began with the SECTION line. Use this when markers are not part of the data you need.

Common Skip zero-byte output files with -z

Some patterns produce empty sections. -z deletes zero-length output files so you do not chase ghost pieces.

Run the command:

bash
cd /tmp/csplit-lab
rm -f xx*
csplit -z report.txt '/NOMATCH/' '{*}'
ls xx*

Sample output:

output
78
xx00

Only the full-file piece remains because /NOMATCH/ never fired to create extra empty segments.

Advanced Limit how many times a pattern runs with {N}

{*} splits at every match. {1} repeats the pattern once more after the first split — useful when you want a header file plus one body chunk before the rest merges.

Run the command:

bash
cd /tmp/csplit-lab
rm -f xx*
csplit report.txt '/SECTION/' '{1}'
ls -l xx*

Sample output:

output
30
22
26
-rw-r--r-- 1 root root 30 Jul  1 17:51 xx00
-rw-r--r-- 1 root root 22 Jul  1 17:51 xx01
-rw-r--r-- 1 root root 26 Jul  1 17:51 xx02

With two SECTION lines in the file, {1} performs one additional split after the first — yielding three pieces total. Use a single line number when you only need exactly two parts.

Advanced Keep partial output when csplit fails (-k)

On error, csplit normally removes output files. -k keeps whatever was already written — helpful in long pipelines when you still want partial results.

Run the command:

bash
cd /tmp/csplit-lab
rm -f xx*
csplit -k report.txt 99999

Sample output:

output
78
csplit: '99999': line number out of range

Despite the error, the first piece remains:

bash
ls xx*
cat xx00

Sample output:

output
xx00
HEADER LINE
line one
line two
SECTION
data a
data b
SECTION
data c
FOOTER
end

Line 99999 is past EOF, so everything landed in xx00.

Advanced Rejoin pieces with cat

csplit does not provide a merge command. Concatenate pieces in sorted name order to rebuild the original bytes (when nothing was suppressed).

Run the command:

bash
cd /tmp/csplit-lab
rm -f xx*
csplit -q report.txt '/SECTION/' '{*}'
cat xx00 xx01 xx02 > restored.txt
diff -u report.txt restored.txt

Sample output:

output
(no diff output — files match)

Use the same prefix order you created (part00.txt, part01.txt, …) when custom -f / -b names were used.


csplit — when to use / when not

Use csplit when Use something else when
  • The file has markers or sections you can match with regex
  • You know exact line numbers where to cut
  • You need content-aware splits (logs, SQL dumps, structured text)
  • Delimiter lines should be stripped (--suppress-matched)
  • You are splitting binary blobs or ISO images by megabytes → split -b
  • You only care about file size or fixed line counts per chunk → GNU split
  • You need stream editing, not physical file cuts → sed or awk
  • One marker defines header vs body → sometimes head/tail is enough

csplit vs split

csplit split
Split rule Regex or line number in the file Bytes, lines, or chunk count
Content aware Yes No — may cut mid-line
Default output xx00, xx01, … xaa, xab, …
Best for Logs, sections, markers Large binaries, transfer-sized chunks

This page covers csplit only. Use GNU split for size-based splitting.


csplit — interview corner

What does the csplit command do?

csplit (context split) breaks one text file into multiple output files at line numbers or regular-expression patterns. It is content-aware — unlike GNU split, which cuts by size.

bash
csplit log.txt '/ERROR/' '{*}'

Creates xx00, xx01, … and prints byte counts for each piece.

A strong answer is:

"csplit splits at regex markers or line numbers — I use it for log sections and structured text; split is for byte or line chunks."

What do {*} and {N} mean in csplit?

They control how many times the preceding pattern repeats:

Form Meaning
{*} Repeat until no more matches
{3} Repeat exactly three more times after the first split

Example:

bash
csplit file.txt '/^---$/' '{*}'    # every --- line starts a new piece
csplit file.txt '/^---$/' '{1}'    # at most one extra split from that pattern

A strong answer is:

"{*} splits on every match; {N} caps how many extra splits follow — both attach to the pattern before them."

When would you use --suppress-matched?

When delimiter lines are not part of the payload — section banners, === separators, XML open tags you do not want duplicated in each chunk.

bash
csplit --suppress-matched data.txt '/^SECTION:/' '{*}'

Each output file starts with content after the marker line.

A strong answer is:

"When marker lines are separators only — suppress-matched drops them from every output piece."

When should you use csplit instead of split?

Use split when size matters: split -b 100M big.iso for transfer limits.

Use csplit when structure matters: stack traces separated by ^--, config stanzas headed by [, repeated Chapter lines.

A strong answer is:

"split for byte or arbitrary line chunks; csplit when the file itself tells you where to cut via patterns or known line numbers."

How do you merge csplit output files?

Concatenate in order:

bash
cat xx* > restored.txt
# or with zero-padded custom names:
cat part00.txt part01.txt part02.txt > restored.txt

Confirm with diff against the original when no lines were suppressed.

A strong answer is:

"cat the pieces in sorted order — csplit has no built-in merge; diff afterward if I used --suppress-matched."


Troubleshooting

Symptom Likely cause Fix
line number out of range Line number past EOF Pick valid lines (wc -l FILE); use -k to keep partial output
Empty xx01 files Pattern matched with nothing between matches Add -z to drop empties; tighten the regex
Pattern never matches Regex typo or wrong case Test with grep -n 'PATTERN' FILE first
Output files removed after error Default cleanup on failure Re-run with -k
Rejoined file differs from original Used --suppress-matched or manual cat order wrong Cat in numeric order; account for removed delimiter lines
invalid pattern Missing / around regex Wrap patterns: '/regex/' not regex

References

Deepak Prasad

R&D Engineer

Founder of GoLinuxCloud with more than 15 years of expertise in Linux, Python, Go, Laravel, DevOps, Kubernetes, Git, Shell scripting, OpenShift, AWS, Networking, and Security. With extensive experience, he excels across development, DevOps, networking, and security, delivering robust and efficient solutions for diverse projects.

  • Go (programming language)
  • Python (programming language)
  • DevOps
  • Computer Security
  • Cloud Computing
  • Kubernetes
  • Linux
  • Ansible (software)