I really liked @NORMAN GEIST's answer but was way too slow for what i needed... So i coded my own version of his script, this time written in Perl Perl (stdin looping and formatting) + Bash Bash (foronly for presentation/help).
You can find the full code herefull code here with an explanation on how to use it.
- A Bash
column
-like command interface (same parameterssame parameters like-t
,-s
,-o
) - Exaustive helphelp with
column_ansi --help
orcolumn_ansi -h
- Option to horizontally center.
The actual "core" code can broken down to only the Perl part:only the Perl part.
perl -e '
use strict;
use warnings;
sub trim_ansi {
my $__temp_string = $_[0];
# Remove all Control Characters (color codes, carriage returns, bells and other characters)
$__temp_string =~ s/ \e[ #%()*+\-.\/]. |
\r | # Remove extra carriage returns also
(?:\e\[|\x9b) [ -?]* [@-~] | # CSI ... Cmd
(?:\e\]|\x9d) .*? (?:\e\\|[\a\x9c]) | # OSC ... (ST|BEL)
(?:\e[P^_]|[\x90\x9e\x9f]) .*? (?:\e\\|\x9c) | # (DCS|PM|APC) ... ST
\e.|[\x80-\x9f] //xg;
1 while $__temp_string =~ s/[^\b][\b]//g; # remove all non-backspace followed by backspace
return $__temp_string
}
# Environment variables used by the program
my $INPUT_SEPARATOR = $ENV{"PCOLUMN_INPUT_SEPARATOR"};
my $OUTPUT_SEPARATOR = $ENV{"PCOLUMN_OUTPUT_SEPARATOR"};
my $ALIGN_RIGHT = $ENV{"PCOLUMN_ALIGN_RIGHT"};
# Default values for INPUT_SEPARATOR and OUTPUT_SEPARATOR
if ($INPUT_SEPARATOR eq ""){
$INPUT_SEPARATOR = " "
}
if ($OUTPUT_SEPARATOR eq ""){
$OUTPUT_SEPARATOR = " "
}
# ALIGN_RIGHT must be a single number or a comma-separated list of numbers
$ALIGN_RIGHT =~ s/^\s+|\s+$//g;
if ($ALIGN_RIGHT ne "" && not $ALIGN_RIGHT =~ /^[0-9]+(,[0-9]+)*$/) {
print STDERR "error: undefined column name '\''$ALIGN_RIGHT'\''\n";
exit 1;
}
my @ALIGN_RIGHT = split(/,/, $ALIGN_RIGHT);
my %ALIGN_RIGHT_HASH = map {$_ - 1 => 1} @ALIGN_RIGHT;
my @stdin = <STDIN>;
my $column_widths = [];
foreach my $line (@stdin) {
$line =~ s/\r?\n?$//;
my @columns = split(/\Q$INPUT_SEPARATOR/, $line);
my $column_index = 0;
foreach my $column (@columns) {
$column = trim_ansi($column);
if (!defined $column_widths->[$column_index]) {
$column_widths->[$column_index] = 0;
}
if ($column_widths->[$column_index] < length($column)) {
$column_widths->[$column_index] = length($column);
}
$column_index++;
}
}
foreach my $line (@stdin) {
$line =~ s/\r?\n?$//;
my @columns = split (/\Q$INPUT_SEPARATOR/, $line);
my $column_index = 0;
foreach my $column (@columns) {
my $__current_column_length = length(trim_ansi($column));
my $__current_column_padding = $column_widths->[$column_index] - $__current_column_length;
if (exists $ALIGN_RIGHT_HASH{$column_index}) {
print(" " x $__current_column_padding);
print($column);
} else {
print($column);
print(" " x $__current_column_padding);
}
if ($column_index != $#columns) {
print($OUTPUT_SEPARATOR);
}
$column_index++;
}
print("\n");
}
';
Background and differences
It was all good, but it was taking way too long to loadway too long to load (as someone pointed in the comments)...