Search code examples
vimalignmenttabular

How to remove a number of spaces between columns and put a custom number of spaces inside?


I have this column:

     USA     France    212     13
  Canada      Spain     34     23
  Me ico      Italy      4    390
   india   Portugal   5900     32
Malaysia    Holland     15     43

I want to remove the spaces like this:

     USA  France 212 13
  Canada   Spain  34 23
  Me ico   Italy   4390
   indiaPortugal5900 32
Malaysia Holland  15 43

and add a custom number of spaces between them
(the same number of spaces between every column).

Is there a way to do this?
(for my left and right-aligned tables)

Edit:
Does anyone know how to check the content of a column (\%.c)?


Solution

  • A solution using 'perl'. I suppose first column is 8 characters width.

    Program:

    use strict;
    use warnings;
    
    ## Hash with contents of each line. Example:
    ## $file{ 1 } = "... line 1 ..."
    ## $file{ 2 } = "... line 2 ..."
    ## ...
    my %file;
    
    ## Max. number of characters of each column.
    ## $col_length[0] will have the max. number of characters of all string of
    ## first column, and the same for the others.
    my @col_length;
    
    while ( <> ) {
            next if /^\s*$/;
            chomp;
    
            ## Save fixed columns in array.
            ## A8 -> 8 characters of first columns.
            ## A11 -> 11 characters of second column.
            ## ...
            my @line = unpack( "A8A11A7A7", $_ );
    
            ## Remove leading and trailing spaces of each field.
            @line = map { s/^\s*//; s/\s*$//; $_ } @line;
    
            ## Save max. number of characters of each column.
            for ( 0 .. $#line ) {
                    my $l = length $line[$_];
                    $col_length[$_] = $l > ($col_length[$_] || 0) ? $l : $col_length[$_]; 
            }
    
            ## Save each input line.
            push @{ $file{ $. } }, @line;
    }
    
    ## Print to output.
    for ( sort { $a <=> $b } keys %file ) {
            my $format = join "", (map { "%" . $_ . "s" } @col_length), "\n";
            printf $format, @{$file{ $_ }};
    }
    

    Input file (infile):

         USA     France    212     13
      Canada      Spain     34     23
      Me ico      Italy      4    390
       india   Portugal   5900     32
    Malaysia    Holland     15     43
    

    Execution:

    $ perl script.pl infile
    

    Output:

         USA  France 212 13
      Canada   Spain  34 23
      Me ico   Italy   4390
       indiaPortugal5900 32
    Malaysia Holland  15 43