Justificando o texto usando o awk

2

Estou tentando formatar meu arquivo de saída para que o texto nas linhas seja distribuído uniformemente para alinhá-lo à esquerda e à direita. Fazer justificação à esquerda e à direita é trivial, mas como alguém pode fazer tanto a esquerda quanto a direita com o awk?

EDITAR

entrada:

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

A saída desejada deve ser algo assim:

This  is  a text
that          is
not  distributed
evenly in a file
    
por mathew7k5b 10.05.2016 / 20:36

2 respostas

2

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.

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).

    
por 10.05.2016 / 21:14
0

Aqui vai você.

    cat file1.txt 
    This is a text
    that is
    not distributed
    evenly in a file

Você disse que "as linhas são distribuídas uniformemente", portanto, a opção "\ t" de delimitar por tabulações deve fazer isso para você.

   cat file1.txt | awk '{print $1 "\t" $2 "\t" $3  "\t" $4 }'

 > file2.txt 

Resultado:

    cat file2.txt 
    This    is  a   text
    that    is      
    not distributed     
    evenly  in  a   file
    
por 10.05.2016 / 21:26