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