Skip to main content
Removed old code
Source Link

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 or column_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)...

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 (stdin looping and formatting) + Bash (for presentation/help).

You can find the full code here.

  • A Bash column-like command interface (same parameters like -t, -s, -o)
  • Exaustive help with column_ansi --help or column_ansi -h

The actual "core" code can broken down to 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

It was all good, but it was taking way too long to load (as someone pointed in the comments)...

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 (stdin looping and formatting) + Bash (only for presentation/help).

You can find the full code here with an explanation on how to use it.

  • A Bash column-like command interface (same parameters like -t, -s, -o)
  • Exaustive help with column_ansi --help or column_ansi -h
  • Option to horizontally center.

The actual "core" code can broken down to only the Perl part.

Background and differences

It was all good, but it was taking way too long to load (as someone pointed in the comments)...

Changed link to repo
Source Link

You can find the full code herehere.

You can find the full code here.

You can find the full code here.

Added ending
Source Link

Enjoy!

Enjoy!

Source Link
Loading