UNIXで列を中央揃えにする方法は?

UNIXで列を中央揃えにする方法は?

コマンドを使用して列を中央揃えしようとしていますcolumn

出力は次のようになります。

temperatures  
    50  
    12  
    89  
    63  

どうすればいいですか?

答え1

私はあなたがそのコマンドを使用したいことを知る前にこの答えを書きましたが、columnそれが必要でない場合は、次のbashシェルスクリプトを使用してテキストを中央に合わせることができます。

#!/bin/bash
set -e    # exit the script if something goes wrong

width=12
data="temperatures 50 12 89 63"

for word in $data; do
    strlen=$(printf $word | wc -c)
    w=$(( ($width - $strlen)/2 ))
    printf "%${w}s%s\n" "" $word
done

仕組み:

  • $width列の幅です
  • for印刷された各単語を繰り返します。$data
  • $strlen現在の単語の長さ(バイト)。
  • $w中央に置く単語の前に印刷されるスペースの数。
  • printf$wスペースの後に単語を印刷します。

出力:

temperatures
     50
     12
     89
     63

このスクリプトは、シングルバイトのテキストエンコーディングでのみ機能します。strlenインクルードを処理するには、この行を変更する必要があります。

答え2

いくつかのファイルが与えられると

temps,temperatures,heatness
500,50,50
1212,12,12
899,89,8989
63,6363,63

このcolumnコマンドはソートされた列を提供しますが、他の特別な調整は提供しません。

$ column -t -s, file
temps         temperatures  heatness
500           50            50
1212          12            12
899           89            8989
63            6363          63

小さなawkスクリプトを使用してセンタリングを実行できます。

$ awk -F, -f center-cols.awk file
temps temperatures heatness
 500       50         50
1212       12         12
 899       89        8989
 63       6363        63
$ awk -F, -v OFS='|' -f center-cols.awk file
temps|temperatures|heatness
 500 |     50     |   50
1212 |     12     |   12
 899 |     89     |  8989
 63  |    6363    |   63

スクリプトcenter-cols.awkは次のとおりです。

function center(w, string,         space, before, after) {
    space  = w - length(string)  # number of spaces in total to fill
    before = int(space/2)        # spaces before string
    after  = space - before      # the rest of spaces after
    return sprintf("%*s%s%*s", before, "", string, after, "")
}

FNR == 1 {
    for (i = 1; i <= NF; ++i)
        width[i] = length($i)
}

{
    for (i = 1; i <= NF; ++i)
        $i = center(width[i], $i)

    print
}

このスクリプトは、各行のヘッダー列(最初の行)の幅に基づいてデータの各列を中央に配置します。これは、ヘッダーよりも長いデータを含む行がまだ正しくソートされていないことを意味します。これらの制限により、スクリプトの実装が簡素化されます。それ以外の場合は、ファイルを2回解析する必要があります。一度は各列の最大列幅を見つけ、一度はデータ型を再指定する必要があります。

スクリプトは最初に各ヘッダー列の幅を取得して配列widthに保存します。次に、対応するcenter関数を使用して各列を再構築します。

このcenter関数は、幅と文字列を使用して、その幅を中心とする文字列を返し、両側にスペースが使用されていないスペースを埋めます。結果の文字列は、sprintf()横のスペースで書かれた書式指定子を使用して構成されます%*s。この指定子は幅と文字列を使用し、計算された幅と実際のデータの前後のスペースを含む空の文字列を提供します(空の文字列は指定された幅にフォーマットされます)。

行のすべての列形式が再指定されると、行が印刷されます。


ファイルを2回解析すると、各列の最大幅を見つけることができます。これにより、列の幅を定義するためにヘッダー行に依存する必要がなくなります。

function center(w, string,         space, before, after) {
    space  = w - length(string)  # number of spaces in total to fill
    before = int(space/2)        # spaces before string
    after  = space - before      # the rest of spaces after
    return sprintf("%*s%s%*s", before, "", string, after, "")
}

NR == 1 {
    for (i = 1; i <= NF; ++i)
        width[i] = length($i)
    next
}

FNR == NR {
    for (i = 1; i <= NF; ++i)
        if (width[i] < length($i))
            width[i] = length($i)
    next
}

{
    for (i = 1; i <= NF; ++i)
        $i = center(width[i], $i)

    print
}

短い列ヘッダーを持つファイルに対して次のコマンドを実行します。

$ awk -F, -v OFS='|' -f center-cols.awk file file
 t  | a  | b
500 | 50 | 50
1212| 12 | 12
899 | 89 |8989
 63 |6363| 63

コマンドラインでファイル名を2回指定する必要があります。

関連情報