2009-10-01 12 views
23

私は2つの列を出力するCプログラムを持っていて、まったく整列していません。ミスアライメントの理由は、最初の列の単語の長さが非常に異なっているためです。テキストの整列していない列を整理する方法を教えてください。

私はviで出力ファイルを開いています。これら2つの列をどのように素早く揃えるには?私はawk、perl、sed、そしてvi(7.2)のツールセットだけでなく、うまく使用できます。また、2つ以上の列を持つファイルの一般的なソリューションもありますか?ここで

は、おそらくあなたが最初の場所での出力に列をprintfを使用している

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

答えて

26

サンプルファイルです。書式文字列に余分な修飾子を使用して、条件が揃うようにすることができます。あなたの文字列が10文字を超える場合

  • は、フォーマットフラグの前に幅を追加します(右詰め)特定の幅の列を印刷するには、例えば、「%10sが」幅10の列を出力します、列はあなたが望むよりも長くなりますので、最大値を選択してください。文字列が短い場合は、スペースで埋められます。
  • 列を左揃えにするには、「%-10s」などの前に記号を付けます。私は文字列を左揃えにし、数字を右寄せするのが好きです。
  • アドレスを印刷している場合は、空白文字から先行する0の "%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]); 
    

    これは、このような3つの列に印刷します::深さの例ではより多くを与えることを

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

はここでawkのソリューションです:c_prog | awk '{ printf("%- 40s %- 40s\n", $1, $2); }'

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, @$_; 
} 
4

あなたは(発電機を固定ではなく)Vimの中で処理を行いたい場合は、見事align pluginをインストールし、以下を実行します。

ggVG 
\tsp 

ggまでの最初のコマンドの区切り(ファイルの先頭に移動)、V(ビジュアルラインモードにする)、G(ファイルの最後に移動)。組み合わせとして、ファイル全体を視覚的に選択します。 \tspは、空白で整列する整列マップです。

あなたは:コマンドラインで物事を行うことを好む場合は、代替のセパレータ(例えば###)を使用すると、コマンドラインの整列を使用することができます。

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

それは長いですが、あなたはより多くのそれを見つけることができます論理的/思い出に残る。間に合わせとフィックス、カラムを通るパイプにそれをするために

33

your_program | column -t 

あなたが列データにスペースを含める必要がある場合、そのようないくつかの文字でフィールドを区切る「|」はおよび:

your_program | column -t -s "|" 

区切り文字には任意の文字を使用でき、-sスイッチで指定できます。制御文字は使用できますが、扱いには少し面倒です。

しかし、Jayが言いましたように、出力を適切にフォーマットするためにプログラムを修正したほうがよいです。

+0

あなたは簡単に例のタブのために、制御文字を指定するには、バッシュの機能を使用することができます。 'column -t -s $ '\ t'' –

+0

警告:列には長すぎる行は好きではなく、' man列 'には2048バイトの制限がありますが、実際には数百バイトでチョークできますそれは(少なくともDebian 8.3で)。 –

2

私はちょうど別の回答の選択肢に欠け追加:などのMx ALIGN-regexpに、のMx ALIGN-文字列、と

Emacsはおそらくビルド中(http://www.emacswiki.org/emacs/AlignCommands

POSIXシェルで続きを読みます)コマンドのprintf

while read f1 f2 f3 tail; do printf "%10s %5s | %s" $f1 $f3 $tail; done <file.txt 
関連する問題