Strip ANSI color codes from output
Remove ESC[…m terminal color sequences from text — for clean log archives, machine-parseable output, and pasting to non-color-aware destinations.
How to strip ansi color codes from output in each shell
noisy-cmd | sed "s/\x1b\[[0-9;]*[mGKHF]//g"GNU sed accepts `\x1b` as the ESC character. Strips the full `CSI parameters terminator` sequence (m=color, G/K=cursor moves, H/F=position). For a tighter "colors only" pattern: `sed "s/\x1b\[[0-9;]*m//g"`.
noisy-cmd | sed "s/\x1b\[[0-9;]*[mGKHF]//g"noisy-cmd | sed "s/\x1b\[[0-9;]*[mGKHF]//g"noisy-cmd | ForEach-Object { [regex]::Replace($_, "`e\[[0-9;]*m", "") }pwsh 6+ supports `` `e `` as the ESC character. On pwsh 5.1: use `[char]27` instead: `[regex]::Replace($_, "$([char]27)\[[0-9;]*m", "")`. The pipeline reads ONE LINE at a time — use `-Raw` upstream for multi-line input.
powershell -NoProfile -Command "noisy.exe | ForEach-Object { [regex]::Replace($_, \"`e\[[0-9;]*m\", \"\") }"cmd has no native ANSI-stripper. The shell-out-to-pwsh approach works. Alternatively: `cmd /c noisy.exe > raw.log` (Windows 10+ Build 1511 enables ANSI rendering in cmd, but the codes are still embedded in stdout — disable color via `NO_COLOR=1` env var or `TERM=dumb` for tools that respect it).
Equivalents listed for Bash, Zsh, Fish, PowerShell, cmd.exe.
Gotchas & notes
- **ANSI escape anatomy**: `ESC [ params terminator` where ESC is byte 0x1B (`\x1b` in GNU sed / `\e` in extended-regex tools / `` `e `` in pwsh 6+ / `[char]27` in pwsh 5.1). `params` is `[0-9;]*` (digits and semicolons). `terminator` is one of `m` (SGR / color), `G K H F` (cursor moves), `J` (clear), `A B C D` (cursor direction). A "colors only" regex `\x1b\[[0-9;]*m` is enough for most log-cleanup; full ANSI strip needs the broader terminator class. The standard tool for this is `ansi2txt` (from the `colorized-logs` package): `noisy-cmd | ansi2txt` — battle-tested, handles edge cases like `OSC` (Operating System Command) `\x1b]…\x07` sequences that pure-regex strippers miss.
- **GNU vs BSD sed escape divergence**: GNU sed accepts `\x1b` (hex escape) inside the pattern: `sed "s/\x1b\[//g"`. BSD/macOS sed does NOT — `\x1b` is treated as literal `x1b`. The portable workaround: use ANSI-C $\'\e\' bash quoting to insert a literal ESC byte: `sed $\'s/\\\e\\[[0-9;]*m//g\'` (the `$\'…\'` is bash-specific and produces a real ESC character). Or use `printf` to emit the byte: `esc=$(printf \'\\033\'); sed "s/${esc}\[[0-9;]*m//g"`. On macOS, `gsed` (from `brew install gnu-sed`) accepts the GNU `\x1b` syntax.
- **Prevention vs cleanup** — far better to PREVENT color emission at the source than strip after: (1) `NO_COLOR=1` env var — a 2018+ convention many tools respect (curl, gcc, ripgrep, fd, bat, eza). (2) `--no-color` / `--color=never` flag — explicit per-tool override. (3) Check `[ -t 1 ]` (stdout is a TTY) — most well-behaved tools auto-disable color when piped (`grep --color=auto` → `--color=never` when not a TTY). (4) `TERM=dumb` — tells curses/terminfo there\'s no color support. The cleanup strategy is only for tools you can\'t control (closed-source vendor scripts, CI output before your script can intercept).
- pwsh `[regex]::Replace` returns a string; `-replace` operator works directly: `$line -replace "`e\[[0-9;]*m", ""`. For BULK file cleanup: `(Get-Content noisy.log -Raw) -replace "`e\[[0-9;]*m", "" | Set-Content clean.log`. The `-Raw` flag reads the entire file as ONE STRING (default is array-of-lines, which makes multi-line regex impossible). pwsh 5.1 doesn\'t support `` `e ``; substitute `[char]27` everywhere. For Windows tools using the older "ANSI.SYS"-style 4-bit colors via Windows console API (not stdout bytes), the stripping is irrelevant — those colors live in the console buffer, not the stream.
Related commands
Related tasks
- Normalize whitespace in text— Collapse multiple spaces / tabs into single spaces and strip line-leading / trailing whitespace — for diff-friendly text, CSV cleanup, and config-file canonicalization.
- Trim leading and trailing whitespace— Remove only the whitespace at the start and end of each line (preserving internal spaces) — for cleaning user input, config-file values, and form fields.
- Find and replace text in files— Substitute one string for another inside a file (or every file in a tree), in place.