ANSI escape codes in Perl — \e, Term::ANSIColor (core), -t STDOUT
Perl supports the `\e` escape in double-quoted strings — the most ergonomic ESC literal across all the ANSI-emitting languages this site documents. `print "\e[31mred\e[0m\n"` works on every Perl back to 5.000 (released 1994), on macOS, Linux, BSDs, and modern Windows (Windows Terminal / Conhost 1709+). For the canonical helper reach for **`Term::ANSIColor`**, a Perl core module bundled with the interpreter since 5.6 — `color("bold red")` returns the escape string, `colored(["bold red"], "text")` wraps text with auto-reset, and `colorstrip("\e[31mred\e[0m")` removes ANSI cleanly (a popular long-tail SERP target). Capability gating uses Perl's idiomatic `-t STDOUT` file test (returns true on a TTY), `IO::Interactive::Tiny::is_interactive` for a portable wrapper, and `$ENV{NO_COLOR}` for the cross-language kill switch. For full TUIs link **`Curses::UI`** (Perl binding for ncurses); for cap-database lookups, **`Term::Cap`** queries terminfo. Perl is still the canonical glue for sysadmin one-liners and log-processing pipelines — the `colorstrip` recipe alone serves a large "how do I strip ANSI from a log file" search demand that lands on Stack Overflow Perl one-liners.
Recommended libraries
- Term::ANSIColor
Perl core module since 5.6 — ships with every Perl interpreter, no install needed. `color("bold red")` returns the SGR escape; `colored(["bold red"], "text")` wraps with auto-reset; `colorstrip($s)` removes all ANSI from a string (the canonical Perl one-liner for log scrubbing). Supports 16, 256, and TrueColor; respects `$ENV{ANSI_COLORS_DISABLED}` and `$ENV{NO_COLOR}`.
- Term::Cap
Perl core module for termcap / terminfo lookup. `Tgetent()` loads the cap entry for `$ENV{TERM}`; `Tputs()` emits a named capability (`cl`, `cm`, `vi`/`ve`, `so`/`se`). Use when you need the correct escape string for the current terminal type rather than the modern de-facto VT bytes.
- IO::Interactive::Tiny
Tiny zero-dep wrapper around the canonical TTY check: `is_interactive($fh)`. Use instead of the raw `-t STDOUT` test when you want a portable answer across redirection, pipes, `IO::Scalar`, and the various "is this a real terminal" edge cases that `-t` doesn't catch.
- Curses::UI
Higher-level Perl TUI framework built on `Curses` (ncurses binding) — windows, dialogs, menus, list boxes, text editors, password input. The right call when you outgrow `Term::ANSIColor` and need a full panel-based UI.
Idiomatic patterns
# Perl supports \e directly in double-quoted strings — the most
# ergonomic ESC literal of any language we document. Single-quoted
# strings do NOT expand \e (or any backslash escapes), so always use
# qq{...} or "..." when emitting ANSI bytes.
use strict;
use warnings;
print "\e[1;31merror:\e[0m permission denied\n";
print "\e[33mwarn:\e[0m deprecated flag\n";
print "\e[32mok:\e[0m 142 tests passed\n";
# Truecolor — 38;2;R;G;B
print "\e[38;2;255;128;0morange truecolor\e[0m\n";use strict;
use warnings;
use Term::ANSIColor qw(color colored colorstrip);
# color() returns the SGR escape string — handcraft your own format:
print color("bold red"), "error:", color("reset"), " permission denied\n";
# colored() wraps text with the open + reset escape — cleaner:
print colored(["bold red"], "error:"), " permission denied\n";
print colored(["yellow"], "warn:"), " deprecated flag\n";
print colored(["green"], "ok:"), " 142 tests passed\n";
# 256-colour and truecolor via named SGR strings:
print colored(["rgb255"], "256-colour red"), "\n";
print colored(["r255g128b0"], "truecolor orange"), "\n";
# colorstrip — remove all ANSI from a string (canonical log scrubber):
my $dirty = "\e[31mERROR\e[0m at line 42";
print colorstrip($dirty), "\n"; # → "ERROR at line 42"use strict;
use warnings;
use Term::ANSIColor;
sub ansi_capable {
# Honour the Unix-standard kill switch first.
return 0 if $ENV{NO_COLOR};
# Term::ANSIColor's own switch — useful inside Term::ANSIColor wrappers.
return 0 if $ENV{ANSI_COLORS_DISABLED};
# Perl's idiomatic TTY check — true when filehandle is on a terminal.
return 0 unless -t STDOUT;
return 1;
}
sub style {
my ($text, $sgr) = @_;
return ansi_capable() ? "\e[${sgr}m${text}\e[0m" : $text;
}
print style("OK", "32"), "\n";
print style("FAIL", "1;31"), "\n";# Perl excels at sysadmin one-liners. These are the canonical
# scrubbers for ANSI in a log / CI output stream.
# Strip ALL ANSI escapes from a file using Term::ANSIColor's colorstrip:
perl -MTerm::ANSIColor=colorstrip -pe '$_ = colorstrip($_)' app.log
# Same with a hand-rolled regex (no module — useful in restricted envs):
perl -pe 's/\e\[[0-9;]*[A-Za-z]//g' app.log
# In-place edit — strip ANSI from many files at once, keep a .bak backup:
perl -i.bak -pe 's/\e\[[0-9;]*[A-Za-z]//g' *.log
# Colourise grep output — emit red+bold for matches, preserve context:
tail -F app.log | perl -MTerm::ANSIColor=colored \
-pe 's/(ERROR|FATAL)/colored([ "bold red" ], $1)/ge'