Spread tabs in padded columns

Looking for a column formatting script, I have the feeling that it could be a single awk line. Ideally, a small shell script is all I need.

The data is divided into a tab, each cell in each row has a variable length and, of course, may contain spaces.

So we have something like this

  dasj dhsahdwe dhasdhajks ewqhehwq dsajkdhas
 e dward das dsaw das daswf
 fjdk ewf jken dsajkw dskdw
 hklt ewq vn1 daskcn daskw

You should get something like this:

  dasj dhsahdwe dhasdhajks ewqhehwq dsajkdhas 
 e dward das dsaw das daswf     
 fjdk ewf jken dsajkw dskdw     
 hklt ewq vn1 daskcn daskw     

Ideally, you can adjust the number of hard intervals between them. Better yet, if it looks column by column, so the leading short cells do not all receive the same legal complement.

Not perfect:

  1 dhsahdwe dhasdhajks ewqhehwq dsajkdhas 
 2 das dsaw das daswf     
 3 ewf jken dsajkw dskdw     
 4 ewq vn1 daskcn daskw     

Ideal:

  1 dhsahdwe dhasdhajks ewqhehwq dsajkdhas 
 2 das dsaw das daswf     
 3 ewf jken dsajkw dskdw     
 4 ewq vn1 daskcn daskw     
+3
source share
3 answers

If you are running BS (including Mac OS X), column (1) and its -t option can do what you want:

% column -t coltest dasj dhsahdwe dhasdhajks ewqhehwq dsajkdhas e dward das dsaw das daswf fjdk ewf jken dsajkw dskdw hklt ewq vn1 daskcn daskw 
+4
source

In un-obsfucated Perl:

 #!/usr/bin/perl -w use strict; my (@data, @length); while (<>) { chomp; my @line = split(/\t/); foreach my $i (0 .. $#line) { my $n = length($line[$i]); $length[$i] = $n if (!defined($length[$i]) || $n > $length[$i]); } push(@data, [ @line ]); } $length[$#length] = 0; # no need to pad the last column my $fmt = join(" ", map { "%-${_}s" } @length) . "\n"; foreach my $ref (@data) { printf $fmt, @$ref; } 
+1
source

Here you go. Tested with gawk.

 BEGIN { FS = "\t"; # max: Column width # fpl: Fields per line # data: Fields in every line } { # Note the blank before this brace fpl[FNR] = NF; for (i=1; i<=NF; i++) { data[FNR, i] = $i; if (length($i) > max[i]) { max[i] = length($i); } } } END { for (l=1; l<=length(fpl); l++) { for (i=1; i<=fpl[l]; i++) { fmt = "%-" max[i] "s"; if (i > 1) { printf " "; # This goes between columns } printf fmt, data[l, i]; } printf "\n"; } } 
+1
source

All Articles