如何清除文本中未对齐的列?

时间:2009-10-01 17:26:20

标签: text

我有一个C程序输出两列,完全未对齐。不对齐的原因是第一列中的单词长度非常不同。

我在vi中打开了一个输出文件。如何快速对齐这两列?我使用awk,perl,sed,而不仅仅是vi(7.2)工具集。另外,我们可以为具有两列以上的文件提供通用解决方案吗?

这是示例文件

column1               column2
-------               -------
sdfsdfsddfsdfsdfsdfsd         343r5
dfgdfgdf             234
gdfgdfgdfgdfgf            645

6 个答案:

答案 0 :(得分:35)

对于快速而肮脏的修复,请通过列管道:

your_program | column -t

如果需要在列数据中包含空格,则使用某些字符(如“|”)分隔字段和

your_program | column -t -s "|"

您可以将任何字符用于分隔符,并使用-s开关指定它。控制字符是可能的,但使用起来有点棘手。

但正如杰伊所说,你最好修复程序以正确格式化输出。

答案 1 :(得分:29)

据推测,您首先使用printf输出列。您可以在格式字符串中使用额外的修饰符,以确保对齐。

  • 要打印特定宽度的列(右对齐),请在格式化标记之前添加宽度,例如,“%10s”将打印宽度为10的列。如果您的字符串长度超过10个字符,则列会比你想要的长,所以选择一个最大值。如果字符串较短,则会用空格填充。
  • 要左对齐列,请在前面加上 - 符号,例如“%-10s”。我个人喜欢左对齐字符串和右对齐数字。
  • 如果要打印地址,可以使用前导零值将填充字符从空格更改为零:“%010x”。

提供更深入的示例:

printf("%-30s %8s %8s\n", "Name", "Address", "Size");
for (i = 0; i < length; ++i) {
    printf("%-30s %08x %8d\n", names[i], addresses[i], sizes[i]);

这将打印三列,如下所示:

Name                            Address     Size
foo                            01234567      346
bar                            9abcdef0     1024
something-with-a-longer-name   0000abcd     2048

答案 2 :(得分:9)

这是一个awk解决方案:c_prog | awk '{ printf("%- 40s %- 40s\n", $1, $2); }'

答案 3 :(得分:4)

如果您想在Vim中进行处理(而不是修复生成器),请安装精湛 align plugin并运行以下命令:

ggVG
\tsp

第一个命令分解为gg(转到文件的开头),V(进入可视线模式),G(转到文件末尾) 。作为一种组合,它可视地选择整个文件。 \tsp是一个Align地图,在白色空间上对齐。

如果您希望在:命令行中执行操作,则可以使用备用分隔符(例如###)并使用命令行对齐:

:%s/\s\+/###/g
:%Align ###
:%s/### //g

它更长,但你可能会发现它更合乎逻辑/更难忘。

答案 4 :(得分:2)

我写了一个小程序,使用Perl解决了这个问题。它也适用于多列。

#!/usr/bin/perl
use strict;
use warnings;
my $sep = 2;

sub max {
    my ($a,$b) = @_;
    return $a > $b ? $a : $b;
}

my @rows;
my $cols;
my $max = 0;

while (<>) {
    next if m/^\s*$/;
    my (@cols) = split m'\s+';

    for (@cols) {
        $max = max($max, length);
    }

    $cols = @cols;
    push @rows, \@cols;
}

for (@rows) {
    my $str = join '', (('%-' . ($max+$sep) . 's') x $cols);
    $str .= "\n";
    printf $str, @$_;
}

答案 5 :(得分:2)

我只是在另一个答案选项中添加了遗漏:

包含M-x align-regexp 的Emacs,M-x align-string 等,请阅读http://www.emacswiki.org/emacs/AlignCommands

的更多内容

POSIX shell(可能内置)命令 printf

while read f1 f2 f3 tail; do printf "%10s %5s | %s" $f1 $f3 $tail; done <file.txt