Se você sabe antecipadamente a largura do alvo, você pode obter uma justificativa básica redistribuindo os espaços em cada linha:
#!/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
}
(com largura padrão de 80; substituir por -v width=...
).
Isso funciona da seguinte maneira:
- linhas sem ou um campo são emitidas como estão;
- cada linha com dois ou mais campos é processada:
- o número de caracteres que não separam campos é contado (
nbchar
); - isso determina o número de espaços para distribuir (
ncspc
); - dividindo isso pelo número de campos menos um dá o número de espaços a serem impressos entre cada campo (arredondado em
spcpf
); - cada campo é impresso, exceto o último; então o número apropriado de espaços é impresso - sempre garantimos que há pelo menos um, e escolhemos
spcpf
, exceto em linhas com apenas dois campos, ou se estivermos imprimindo o segundo último campo, caso em que há muitos espaços são deixados (nbspc
é ajustado para acompanhar); - finalmente o último campo é impresso, com uma nova linha.
- o número de caracteres que não separam campos é contado (
Se você deseja segmentar a largura do texto existente, inicialize width
usando algo assim:
awk 'length > max { max = length }; END { print max }'
(Eu não sei de uma maneira infalível de redefinir o fluxo de entrada em awk
- você sempre pode especificar que é um arquivo e adaptar o script de acordo.)
Isso produz
This is a text
that is
not distributed
evenly in a file
com largura 16 (a largura do texto existente) ou
This is a text
that is
not distributed
evenly in a file
com largura 20 ou
This is a text
that is
not distributed
evenly in a file
com largura 12 (linhas transbordam).