highlight.pl

This is a script I've wanted to share for a while, but I haven't yet had the chance to figure out how to write App::Highlight (if anybody could give me some pointers in this direction it would be much appreciated!)

highlight.pl is designed to be piped into, like grep or ack, but instead of filtering out lines which don't match it just highlights words which do, similar to "ack --passthru" except that you get different coloured highlights for your different matches.


#!/usr/bin/perl

#
# pipe text to highlight.pl to highlight certain words
#
# eg. cat nastyfile.pl | highlight words you want
#

use strict;
use warnings;

use Term::ANSIColor qw/:constants/;
use Getopt::Long;

my ($no_escape,$full_line);
GetOptions(
'no-escape|n' => \$no_escape,
'full-line|l' => \$full_line,
'help|h' => sub { print usage(); exit 0 },
);

my @matches = (".+");
if (scalar @ARGV) {
if ($no_escape) {
@matches = @ARGV;
}
elsif ($full_line) {
@matches = map { qr/^.*\Q$_\E.*$/ } @ARGV;
}
else {
@matches = map { "\Q$_" } @ARGV;
}
}

my @colors = map { BOLD $_ } (
RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN
);

my $reset = RESET;

while () {
my $i = 0;
foreach my $m (@matches) {
s/($m)/$colors[$i] . $1 . $reset/ge;

$i++; $i %= @colors;
}
print;
}

exit 0;

##########################################

sub usage {
return <<" END";
$0
--no-escape [n] don't autoescape input, for using regular expressions
--full-line [l] highlight the entire line that contains the match
--help [h] show this message
END
}

As a bonus, here's an alias I find very useful:


alias svndiff="svn diff | highlight -n '^[-][^-].*$' '^[+][^+].*$' '^(([-+]{2,})|([=]{5,})).+'"

This highlights filename headers in yellow, added lines in green and deleted lines in red.

Feedback welcome :) This is the first time I'm showing this code so it's probably very rusty and inefficient (I just noticed that svndiff would be simpler to write if --full-line and --no-escape worked together!)

- Alex

Leave a comment

About Alex Balhatchet

user-pic CTO at Lokku Ltd.