#!/usr/bin/env perl # archive_color (by Wolfgang Friebel), a slightly enhanced tarcolor # changed date recognition (allow for localized dates), works also for # other archive listings, such as rpm, debian, ar, isoinfo archives # # originally by Marc Abramowitz # # https://github.com/msabramo/tarcolor # # Colors output of `tar tvf` similarly to the way GNU ls (in GNU # coreutils) would color a directory listing. # # Colors can be customized using an environment variable: # # TAR_COLORS='di=01;34:ln=01;36:ex=01;32:so=01;40:pi=01;40:bd=40;33:cd=40;33:su=0;41:sg=0;46' # # The format for TAR_COLORS is similar to the format used by LS_COLORS # Check out the online LSCOLORS generator at http://geoff.greer.fm/lscolors/ use warnings; use strict; my $RESET = "\033[0m"; sub get_file_type { return if (length($_) < 10); if (substr($_, 0, 1) eq 'l') { return 'ln'; } elsif (substr($_, 0, 1) eq 'd') { return 'di'; } elsif (substr($_, 0, 1) eq 's') { return 'so'; } elsif (substr($_, 3, 1) eq 'S') { return 'su'; } elsif (substr($_, 6, 1) eq 'S') { return 'sg'; } elsif (substr($_, 0, 1) eq 'p') { return 'pi'; } elsif (substr($_, 0, 1) eq 'c') { return 'cd'; } elsif (substr($_, 0, 1) eq 'b') { return 'bd'; } elsif (substr($_, 0, 1) eq 'D') { return 'do'; } elsif (substr($_, 3, 1) eq 'x') { return 'ex'; } elsif (substr($_, -3, 2) =~ /.\//) { return 'di'; } elsif (/\.\w{1,3}$/) { return '*' . $&; } } sub get_filename { my $suntar_date = m{ (?: [A-Z]\w\w) # Month \s+ \d{1,2} # Day \s+ \d{2}:\d{2} # Time \s+ \d{4} # Year [\s,]+ (.+?) # Capture group 1: filename (?=\s->|$) }gx; if ($suntar_date) { return $1, pos(); } my $bsdtar_date = m{ (?: [A-Z]\w\w) # Month \s+ \d{1,2} # Day \s+ (?: (?: \d{4}) | (?: \d{2}:\d{2})) # Year or time \s (.+?) # Capture group 1: filename (?=\s->|$) }gx; if ($bsdtar_date) { return $1, pos(); } my $bsdtar_date_dmy = m{ \d{1,2} # Day \s+ (?: [A-Z]\w\w) # Month \s+ (?: (?: \d{4}) | (?: \d{2}:\d{2})) # Year or time \s+ (.+?) # Capture group 1: filename (?=\s->|$) }gx; if ($bsdtar_date_dmy) { return $1, pos(); } my $gnutar_date = m{ \d{4}-\d{2}-\d{2} # Date (%Y-%m-%d) \s \d{2}:\d{2} # Time (%H:%M) (?: :\d{2})? # [Optional] seconds in time \s+ (.+?) # Capture group 1: filename (?=\s->|$) }gx; if ($gnutar_date) { return $1, pos(); } } sub color_filename { my ($color) = @_; my ($filename, $pos) = get_filename(); if ($filename && $pos) { substr($_, $pos - length($filename), length($filename)) = $color . $filename . $RESET; } } sub default_ls_colors { return ''; } if ( -t STDIN ) { print "Example: tar tvzf some_tarball.tar.gz | archive_color\n"; exit(0); } my %FILE_TYPE_TO_COLOR = ( "di" => "\033[01;34m", "ln" => "\033[01;36m", "ex" => "\033[01;32m", "so" => "\033[01;35m", "pi" => "\033[40;33m", "bd" => "\033[40;33;01m", "cd" => "\033[40;33;01m", "su" => "\033[37;41m", "sg" => "\033[30;43m", ); my $tar_colors = $ENV{'TAR_COLORS'} || $ENV{'LS_COLORS'} || default_ls_colors(); foreach (split(':', $tar_colors)) { my ($type, $codes) = split('='); $FILE_TYPE_TO_COLOR{$type} = "\033[" . $codes . "m"; } while (<>) { my $type = get_file_type(); if ($type && $FILE_TYPE_TO_COLOR{$type}) { color_filename($FILE_TYPE_TO_COLOR{$type}); } print; } # ABSTRACT: colors output of `tar tvf` # PODNAME: archive_color =pod =head1 SYNOPSIS tar tvzf | archive_color =head1 DESCRIPTION Tarcolor colors the output of `tar tvf` similarly to how ls does it. Colors output of `tar tvf` similarly to the way GNU ls (in GNU coreutils) would color a directory listing. Colors can be customized using an environment variable: TAR_COLORS='di=01;34:ln=01;36:ex=01;32:so=01;40:pi=01;40:bd=40;33:cd=40;33:su=0;41:sg=0;46' The format for TAR_COLORS is similar to the format used by LS_COLORS Check out the online LSCOLORS generator at http://geoff.greer.fm/lscolors/ =head1 SEE ALSO tarcolorauto(1) =head1 SOURCE CODE https://github.com/msabramo/tarcolor =cut