csplit: Split a File by Pattern in CI
csplit divides a file into sections at line numbers or lines matching a regular expression.
When a log or multi-document YAML needs cutting at markers rather than every N bytes, csplit splits on a pattern. It writes numbered pieces like xx00, xx01.
What it does
csplit reads a file and writes segments split at each given line number or /regex/ match, into files named xx00, xx01, ... {N} repeats a pattern N times and {*} repeats until end of file. Unlike split (which cuts by size/lines), csplit cuts at content boundaries. Part of coreutils.
Common usage
# split a multi-doc YAML at each '---' separator
csplit -z -f doc- -b '%02d.yaml' input.yaml '/^---$/' '{*}'
# split a log at every line starting with a timestamp header
csplit access.log '/^==== /' '{*}'
# split at line 100
csplit report.txt 100
# suppress the byte-count lines csplit prints
csplit -s data.txt '/SECTION/' '{*}'Options
| Flag / arg | What it does |
|---|---|
| /regex/ | Split before each line matching regex |
| {N} / {*} | Repeat the preceding pattern N times / to EOF |
| -f <prefix> | Output file name prefix (default xx) |
| -b <fmt> | printf format for the numeric suffix |
| -z, --elide-empty-files | Do not create empty output pieces |
| -s, --silent | Do not print output byte counts |
| -k | Keep files even if an error occurs |
In CI
To process a rendered multi-document manifest, split it into per-document files with csplit -z (elide empties) so a leading --- does not create an empty xx00. Use -b to give the pieces meaningful names and extensions your next tool expects, rather than the default xx00.
Common errors in CI
"csplit: /pattern/: match not found" means the regex never matched and, by default, csplit deletes the partial output it created; add -k to keep pieces or fix the pattern. A stray empty xx00 appears when the pattern matches at the very start; add -z. On failure without -k, all xx* files are removed, which can look like csplit "did nothing".