awkを使用したテキストの並べ替え

awkを使用したテキストの並べ替え

行のテキスト間隔が均等で左右に揃えるように出力ファイルをフォーマットしようとしています。左右のソートを行うのは簡単ではありませんが、awkを使用して左右のソートを行うにはどうすればよいですか?

編集する

入力する:

This is a text
that is
not distributed
evenly in a file

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

This  is  a text
that          is
not  distributed
evenly in a file

ベストアンサー1

ターゲット幅を事前に知っている場合は、各行の空白を再配布して基本的な正当化を得ることができます。

#!/usr/bin/awk -f

BEGIN {
    if (width == 0) width = 80
}

NF <= 1 { print }

NF > 1 {
    nbchar = 0
    for (i = 1; i <= NF; i++) {
        nbchar += length($i)
    }
    nbspc = width - nbchar
    spcpf = int(nbspc / (NF - 1))
    for (i = 1; i < NF; i++) {
        printf $i
        spaces = (NF == 2 || i == NF - 1) ? nbspc : spcpf
        if (spaces < 1) spaces = 1
        for (j = 0; j < spaces; j++) {
            printf " "
        }
        nbspc -= spaces
    }
    print $NF
}

(デフォルトの幅は80です。overrideを使用してください-v width=...)。

仕組みは次のとおりです。

  • フィールドがないか、またはフィールドが1つだけある行は、そのまま出力されます。
  • 複数のフィールドを持つ各行を処理します。
    • nbcharフィールド区切り文字ではない文字()の数を計算します。
    • 割り当てるスペースの量を決定します(ncspc)。
    • これをフィールド数から1を引いたもので除算して、各フィールド間に印刷するスペースの数を取得します(では丸められますspcpf)。
    • spcpf最後のフィールドを除くすべてのフィールドが印刷されます。その後、適切な数のスペースが印刷されます。 2つのフィールドしかない行がない場合、または最後に2番目のフィールドを印刷していない場合は、常に少なくとも1つがあることを確認して選択します。この場合、残りのスペースの数に関係なく(nbspc追跡を維持するように調整)。
    • 最後に、最後のフィールドを印刷し、新しい行で囲みます。

既存のテキストの幅をターゲットにするには、width次のように初期化します。

awk 'length > max { max = length }; END { print max }'

(入力ストリームをリセットする明確な方法はありません。awkいつでもファイルであることを指定し、それに応じてスクリプトを調整できます。)

これは生産します

This is a   text
that          is
not  distributed
evenly in a file

幅16(既存のテキストの幅)または

This   is   a   text
that              is
not      distributed
evenly  in  a   file

幅が20

This is a text
that      is
not distributed
evenly in a file

幅は12です(これにより行がオーバーフローします)。

おすすめ記事