Not sure if this counts as "cool use" but this little thing has become one of my favorite tools over the past few years. Pass any plaintext data through it and emphasize any text you want using regular expressions. Useful for tcpdump, server logs...anything really.
Update: After posting version 1 the problem of overlapping matches has been bugging me so much I've actually found a solution. Instead of using straight regex substitution I now do all the matching first, then apply the colors afterwards. I've tested it quite a bit but it's still experimental.
#!/usr/bin/perl
use strict;
use warnings;
use Term::ANSIColor;
my @rules = @ARGV;
while (my $line = <STDIN>) {
print rewrite($line, @rules);
}
exit;
# Process a single line
sub rewrite {
my $line = shift;
my @rules = @_;
my @marks = ();
# Process each rule and find areas to mark
while (@rules) {
my $regex = shift @rules;
my $color = shift @rules || 'bold yellow';
$color = color('reset').color($color);
while ($line =~ /$regex/ig) {
my $reset = undef;
# Scan match area to find last color
foreach my $i (reverse $-[0] .. $+[0]) {
if (defined $marks[$i]) {
$reset = $marks[$i] unless defined $reset;
$marks[$i] = undef; # Cancel previous color
}
}
# If necessary, keep scanning to beginning of line
unless (defined $reset) {
foreach my $i (reverse 0 .. $-[0]) {
if (defined $marks[$i]) {
$reset = $marks[$i];
last;
}
}
}
# Mark area
$marks[$-[0]] = $color;
$marks[$+[0]] = $reset || color('reset');
}
}
# Apply color codes to the string
foreach my $i (reverse 0 .. $#marks) {
substr($line, $i, 0, $marks[$i]) if defined $marks[$i];
}
return $line;
}
=pod
=head1 NAME
em - console emphasis tool version 2
=head1 DESCRIPTION
em is a command line tool for visually emphasizing text in log files e
+tc. by
colorizing the output matching regular expressions.
=head1 SYNOPSIS
em REGEX1 [COLOR1] [REGEX2 [COLOR2]] ... [REGEXn [COLORn]]
=head1 USAGE
REGEX is any regular expression recognized by Perl. For some shells
this must be enclosed in double quotes ("") to prevent the shell from
interpolating special characters like * or ?.
COLOR is any ANSI color string accepted by Term::ANSIColor, such as
'green' or 'bold red'.
Any number of REGEX-COLOR pairs may be specified. If the number of arg
+uments
is odd (i.e. no COLOR is specified for the last REGEX) em will use 'bo
+ld yellow'.
Overlapping rules are supported. For characters that match multiple ru
+les,
only the last rule will be applied.
=head1 EXAMPLES
In a system log, emphasize the words "error" and "ok":
=over
tail -f /var/log/messages | em error red ok green
=back
In a mail server log, show all email addresses between <> in white, su
+ccesses in green:
=over
tail -f /var/log/maillog | em "(?<=\<)[\w\-\.]+?\@[\w\-\.]+?(?=\>)" "b
+old white" "stored message|delivered ok" "bold green"
=back
In a web server log, show all URIs in yellow:
=over
tail -f /var/log/httpd/access_log | em "(?<=\"get).+?\s"
=back
=head1 BUGS AND LIMITATIONS
Multi-line matching is not implemented.
All regular expressions are matched without case sensitivity.
=head1 AUTHOR
Andreas Lund <floyd@atc.no>
=head1 COPYRIGHT AND LICENSE
Copyright 2009-2013 Andreas Lund <floyd@atc.no>. This program is free
+software;
you may redistribute it and/or modify it under the same terms as Perl
+itself.
=cut
1. I would love for someone to adopt this and put it on CPAN so myself and others can get easy access to it
2. There's one annoying limitation; overlapping matches don't behave the way they should, and I can't find a way to fix it.
Update: There is one other cool way to use this tool, and that's regex testing. Simply type "em" and the regex you want to test. Example:
em "0x[0-9a-f]+"
Now input your test strings one by one, and "em" will show you exactly what matches and what doesn't. Hit Ctrl+D (EOF) to exit.
--
Time flies when you don't know what you're doing
-
Are you posting in the right place? Check out Where do I post X? to know for sure.
-
Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
<code> <a> <b> <big>
<blockquote> <br /> <dd>
<dl> <dt> <em> <font>
<h1> <h2> <h3> <h4>
<h5> <h6> <hr /> <i>
<li> <nbsp> <ol> <p>
<small> <strike> <strong>
<sub> <sup> <table>
<td> <th> <tr> <tt>
<u> <ul>
-
Snippets of code should be wrapped in
<code> tags not
<pre> tags. In fact, <pre>
tags should generally be avoided. If they must
be used, extreme care should be
taken to ensure that their contents do not
have long lines (<70 chars), in order to prevent
horizontal scrolling (and possible janitor
intervention).
-
Want more info? How to link
or How to display code and escape characters
are good places to start.