Вкладка данных с разделителями

В поисках сценария форматирования столбца, я чувствую, что это может быть одна строка awk. В идеале, маленький сценарий оболочки это все, что я после.

Данные разделены табуляцией, каждая ячейка в каждой строке имеет переменную длину, и, конечно, в ней могут быть пробелы.

Итак, у нас есть что-то вроде этого

дасдж дхсахдве дхасдхаджкс эвхехвк дсаджкдхас
e dward das dasaw daswf
fjdk ewf jken dsajkw dskdw
hklt ewq vn1 daskcn daskw

Должно получиться что-то вроде этого:

дасдж дхсахдве дхасдхаджкс эвхехвк дсаджкдхас 
e dward das dasaw daswf     
fjdk ewf jken dsajkw dskdw     
hklt ewq vn1 daskcn daskw     

В идеале, возможность регулировать количество жестко разнесенных между каждым. Еще лучше, если он выглядит по столбцам, поэтому ведущие короткие ячейки не все получают одинаковое правильное заполнение.

Не идеально:

1 dhsahdwe dhasdhajks ewqhehwq dsajkdhas 
2 das dasaw       das        daswf     
3       ewf        jken       dsajkw     dskdw     
4 EWQ VN1 DASKCN DASKW     

Идеально:

1 dhsahdwe dhasdhajks ewqhehwq dsajkdhas 
2 das dasaw       das        daswf     
3       ewf        jken       dsajkw     dskdw     
4 EWQ VN1 DASKCN DASKW     

3 ответа

Если вы работаете с операционной системой BSD (включая Mac OS X), столбец (1) и его опция -t могут делать то, что вы хотите:

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

Ну вот. Протестировано с "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";
    }
}

В необъявленном 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;
}
Другие вопросы по тегам