选项卡间隔数据到填充列

时间:2008-12-02 08:12:28

标签: tabs alignment spaces

寻找列格式化脚本,我觉得这可能是一行awk。理想情况下,我所追求的是一个小的shell脚本。

数据以制表符分隔,每行中的每个单元格长度可变,当然,其中可能有空格。

所以我们有类似的东西

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

应该结束这样的事情:

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

理想情况下,能够调整每个之间的硬间隔量。如果它逐列查找更好,那么前导短单元并不都能获得相同的正确填充。

不理想:

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

理想:

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

3 个答案:

答案 0 :(得分:4)

如果您使用的是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

答案 1 :(得分:1)

未受阻的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;
}

答案 2 :(得分:1)

你走了。用“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";
    }
}