How to strip ANSI codes from a log
By Flavio
Remove ANSI color and hyperlink escapes from a terminal log in the browser. CSI, OSC, and other 7-bit sequences go. The plain text stays.
Free toolThis tutorial uses the ANSI Escape Stripper. It runs in your browser, so open it in another tab and follow along.
A terminal does not store color as a style. It stores bytes. A program writes an ESC character, then a short sequence, then the text you were meant to read. The terminal paints the text and hides the sequence. A log file keeps both.
That is why a captured test log looks like garbage in an editor, and why a search for the word error misses it when the letters are wrapped in a color sequence. The ANSI escape stripper deletes those sequences and leaves the text. It runs in the browser. The log is not stored in the URL.
What an escape is
ESC is the character U+001B. You will see it written as \x1b, \033, or \u001b. The next byte says which family you are in.
CSI starts with ESC [. Then come parameter bytes, in the range 0 to ?, then optional intermediate bytes, then one final byte from @ to ~. Color is a CSI sequence whose final byte is m. Cursor movement, erase, and bold are CSI too. This page removes the whole sequence. It does not try to keep bold and drop only color.
OSC starts with ESC ]. Operating system commands include the window title and the hyperlink form, OSC 8. The sequence runs until BEL, which is byte 0x07, or until ST, which is ESC followed by \. The URL of a hyperlink sits inside the sequence. The visible label sits after it. Strip the sequence and the label remains.
A few sequences are shorter. ESC c resets the terminal. ESC ( B selects a character set. Those are removed as well. A lone ESC at the end of the file, with nothing after it, is removed and noted.
Bytes from 0x80 to 0x9F are the 8-bit C1 controls. This page does not strip them. In UTF-8 those same bytes are continuation bytes. Stripping them would break é and most non-ASCII text. If your log is Latin-1 and uses raw C1 controls, they will still be in the output.
Strip the sample
Open the ANSI escape stripper and click Load sample. The sample is three lines. The first wraps error in red, then resets. The second is an OSC 8 hyperlink whose label is flaviocopes.com, closed by an empty OSC 8. The third wraps ready in bold green.
SGR parameter 31 is the foreground red from the original 8-color set. 0 resets. 1;32 is bold, then green. The semicolon separates parameters inside one CSI sequence. OSC 8 has the shape ESC ] 8 ; ; URL ST, then the visible label, then ESC ] 8 ; ; ST with an empty URL to close the link. The label flaviocopes.com is ordinary text between those two sequences, so it survives.
The sample, with the escapes still in it, is:
[31merror[0m: disk full
]8;;https://flaviocopes.com\flaviocopes.com]8;;\
[1;32mready[0m
The summary is:
Sequences removed: 6
CSI: 4
OSC: 2
Other: 0
error: disk full
flaviocopes.com
ready
Four CSI sequences are the two color openings and the two resets: ESC [ 31 m, ESC [ 0 m, ESC [ 1 ; 32 m, and another ESC [ 0 m. Two OSC sequences are the hyperlink open, which contains https://flaviocopes.com, and the hyperlink close, which is empty. The visible words were never inside a sequence, so they stay, including the colon and the newline.
The count line is part of the summary that Copy and Download use. If you need the plain text alone, it starts after the blank line.
A program that writes the same colors with \033[38;2;255;215;0m is still CSI. The parameters are longer, the final byte is still m, and the sequence still goes. That is the form used in the lolcat CLI in Go, where each character is printed with an RGB escape and then reset.
A sequence that never finishes
A log that was cut off can end inside a sequence. Paste keep followed by ESC [ 31 and nothing else:
Sequences removed: 0
CSI: 0
OSC: 0
Other: 0
keep
The note is: An unfinished CSI at the end was removed. The counts stay at zero because the sequence never reached a final byte, so it is not counted as a removed CSI. The unfinished bytes are still gone, which is what you want in a log you are about to store. The note tells you the cut happened.
A different break is a CSI that hits a character that cannot finish it. Paste ESC [ 31, then a newline, then next. The summary still starts with the four count lines, and the plain text keeps the broken sequence:
Sequences removed: 0
CSI: 0
OSC: 0
Other: 0
[31
next
The bytes after the blank line are ESC, [, 31, a newline, and next. The note is: A CSI sequence was cut short and the rest was left in the text. A newline is not a legal place to end CSI, so the page refuses to swallow the rest of the line. You can see the broken sequence and decide what to do. That is a different choice from the unfinished-at-the-end case, where there is no later text to protect.
café is left alone. The é is UTF-8 bytes c3 a9. The second byte sits in the C1 range, and it stays. The summary says Sequences removed: 0.
A charset designation is the Other count, not CSI. ESC ( B selects US-ASCII under the old G0 rules, and ESC c is the reset sequence RIS. Together they are two sequences. The summary says Sequences removed: 2, CSI: 0, OSC: 0, Other: 2, and the remaining text is plain. You will see Other move when a full-screen app wrote a reset or a charset shift into the log. Color stays in the CSI count. Hyperlinks stay in the OSC count.
What goes wrong
An empty box says: Paste a terminal log. A string over 1,000,000 characters is refused. A file over 1 MB is refused before it is read, with the file name and the size.
The page counts three families. CSI is ESC [. OSC is ESC ]. Other is everything else that started with ESC and was fully removed, including a charset shift and ESC c. An unfinished sequence is noted and is not added to those counts.
OSC that contains an ESC which is not the start of ST ends at that ESC. The following bytes are parsed again, so a second sequence is not eaten by the first one. If the file ends in the middle of an OSC, the note says an unfinished OSC at the end was removed.
Newlines, tabs, and spaces are text. They stay. The page does not trim the log and does not collapse blank lines. If you wanted that, you wanted a different tool.
When the page is the wrong tool
Use this page when a log, a test transcript, or a copied terminal already contains escapes and you want the words. Search, diff, and paste all get easier once the CSI and OSC bytes are gone.
Use the text cleaner when the problem is whitespace, quotes, or invisible characters, and there is no ESC in the file. Use the JSON formatter when the payload is JSON and the escapes are inside a string you still want to parse. Stripping first can help, and then the formatter is the tool that understands the JSON. Use Unicode character search when you need the code point of one character, including ESC itself.
Libraries such as Node’s util.stripVTControlCharacters do this in a program. Chalk and util.styleText write the sequences. Output to the command line using Node shows the \x1b[33m form and why a library is easier to write. This page is for the log you already have, when you do not want to run a command to clean it.
Try the ANSI Escape Stripper
Paste a terminal log and remove CSI colors, OSC hyperlinks, and other ECMA-48 escapes. The plain text stays in the browser and is not stored in the URL.
Open the ANSI Escape Stripper →
Related tools
- Text Cleaner & Whitespace Remover: Collapse spaces, clean blank lines, normalize line endings, expand tabs, or turn pasted text into one line.
- JSON Formatter & Validator: Validate, pretty-print, and minify JSON with clear error messages. Runs entirely in your browser.
- Unicode Character Search: Find any character by name or paste one to decode it — code points, UTF-8 bytes, and HTML, JS, CSS escapes with copy buttons.
Want me to talk about your product? You can sponsor this site.