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

Text 如何清理文本中未对齐的列?,text,Text,我有一个C程序,输出两列,完全不对齐。不对齐的原因是第一列中的单词长度非常不同 我在vi中打开了一个输出文件。如何快速对齐这两列?我可以使用awk、perl、sed,而不仅仅是vi(7.2)工具集。另外,我们能为超过两列的文件提供一个通用解决方案吗 这是示例文件 column1 column2 ------- ------- sdfsdfsddfsdfsdfsdfsd 343r5 dfgdfgdf 2

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

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

这是示例文件

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

假设您首先使用
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]);

这里有一个awk解决方案:
c|u prog|awk'{printf(“%-40s%-40s\n”,$1,$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, @$_;
}
#/usr/bin/perl
严格使用;
使用警告;
我的$sep=2;
次最大值{
我的($a$b)=;
返回$a>$b?$a:$b;
}
我的@行;
我的$cols;
我的$max=0;
而(){
下一步如果m/^\s*$/;
my(@cols)=拆分m'\s+';
for(@cols){
$max=max($max,长度);
}
$cols=@cols;
按@行,\@列;
}
对于(@行){
我的$str=加入“”,((“%-”($max+$sep)。“s”)x$cols);
$str.=“\n”;
printf$str,@$\;
}

如果要在Vim中进行处理(而不是修复发电机),请安装superb并运行以下操作:

ggVG
\tsp
第一个命令分解为
gg
(转到文件的开头)、
V
(进入可视行模式)、
G
(转到文件的结尾)。作为组合,它可以直观地选择整个文件
\tsp
是在空白处对齐的对齐贴图

如果您喜欢在
命令行中执行操作,可以使用替代分隔符(例如
###
)并使用命令行对齐:

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

它更长,但您可能会发现它更符合逻辑/更令人难忘。

要快速解决问题,请通过以下列将其导入:

your_program | column -t
如果需要在列数据中包含空格,请使用一些字符(如“|”和:

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


但正如Jay提到的,最好修复程序,以正确格式化输出。

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

带有M-x对齐regexp、M-x对齐字符串等的Emacs。请阅读

POSIX shell(可能内置)命令printf

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

读取f1 f2 f3尾部时
;打印“%10s%5s |%s”$f1$f3$tail;完成后,您可以使用Bash的一个功能轻松指定控制字符,例如Tab:
column-t-s$'\t'
警告:column不喜欢“太长”的行,虽然
man column
提到限制为2048字节,但实际上几百字节就足以阻塞它(至少在Debian 8.3上)。
your_program | column -t -s "|"
while read f1 f2 f3 tail; do printf "%10s %5s | %s" $f1 $f3 $tail; done <file.txt