行のテキスト間隔が均等で左右に揃えるように出力ファイルをフォーマットしようとしています。左右のソートを行うのは簡単ではありませんが、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です(これにより行がオーバーフローします)。