Formata texto no Linux

0

Estou tentando formatar dados em um arquivo que precisa ser importado para um sistema. Este sistema não leva mais de 65 caracteres de texto em uma única linha. Portanto, estou tentando formatar o texto na coluna Descrição para dividir como várias linhas, conforme mostrado na amostra abaixo. Seria muito útil para o usuário se é um comando Linux de linha única, você pode por favor verificar se é possível?

Exemplo de entrada no arquivo -

 
Depth   Description
(ft)    -
12370.0 LS: Mdst, blsh gry, sft, occ mod firm, crpxln, prly, arg, SLTST: blk, firm-mod hd, amor, gt, mod calc, CLST: lt gry-m gry, sft, amor, wxy
12400.0 LS: Mdst, blsh gry, mod firm, crpxln, chky, arg, SLTST: blk-dk gry, firm-mod hd, amor, gt, mod calc, CLST: lt gry-m gry, occ rdsh gry, mod firm, amor, wxy, tr CHK
12430.0 LS: Mdst, blsh gry, mod firm, crpxln, chky, arg, SLTST: blk-dk gry, firm-mod hd, amor, gt, mod calc, SH: blk-dk gry, mod firm, blky-plty, occ brit, wxy
12460.0 SH: blk-dk gry, mod firm, blky-plty, occ brit, ea, SLTST: blk-dk gry, firm-mod hd, amor, gt, mod calc, SST: gry-dk gry, wl consol, v f, ang, p srt, cotd, slily calc cmt, no fluor

Profundidade e descrição e a linha abaixo são considerados cabeçalhos. A coluna Profundidade contém todos os números, a coluna Descrição contém texto que deve ser formatado como várias linhas para o sistema aceitar os dados.

Saída desejada com comando Linux -

 
Depth   Description
(ft)    -
12370.0 LS: Mdst, blsh gry, sft, occ mod firm, 
        crpxln, prly, arg, SLTST: blk, firm-mod hd, 
        amor, gt, mod calc, CLST: lt gry-m gry, sft, 
        amor, wxy
12400.0 LS: Mdst, blsh gry, mod firm, crpxln, chky, 
        arg, SLTST: blk-dk gry, firm-mod hd, amor, 
        gt, mod calc, CLST: lt gry-m gry, occ rdsh gry, 
        mod firm, amor, wxy, tr CHK
12430.0 LS: Mdst, blsh gry, mod firm, crpxln, chky, 
        arg, SLTST: blk-dk gry, firm-mod hd, amor, 
        gt, mod calc, SH: blk-dk gry, mod firm, 
        blky-plty, occ brit, wxy
12460.0 SH: blk-dk gry, mod firm, blky-plty, occ brit, 
        ea, SLTST: blk-dk gry, firm-mod hd, amor, gt, 
        mod calc, SST: gry-dk gry, wl consol, v f, ang, 
        p srt, cotd, slily calc cmt, no fluor

Nota - O usuário não poderá instalar nenhum pacote Linux em suas máquinas. (exemplo - par)

    
por NewCoder 05.09.2017 / 18:28

3 respostas

1

Com o GNU sed :

$ sed -r '3,$s/(.{55} )/\n\t/g' file.in
Depth   Description
(ft)    -
12370.0 LS: Mdst, blsh gry, sft, occ mod firm, crpxln, prly,
        arg, SLTST: blk, firm-mod hd, amor, gt, mod calc, CLST:
        lt gry-m gry, sft, amor, wxy
12400.0 LS: Mdst, blsh gry, mod firm, crpxln, chky, arg,
        SLTST: blk-dk gry, firm-mod hd, amor, gt, mod calc, CLST:
        lt gry-m gry, occ rdsh gry, mod firm, amor, wxy, tr CHK
12430.0 LS: Mdst, blsh gry, mod firm, crpxln, chky, arg,
        SLTST: blk-dk gry, firm-mod hd, amor, gt, mod calc, SH:
        blk-dk gry, mod firm, blky-plty, occ brit, wxy
12460.0 SH: blk-dk gry, mod firm, blky-plty, occ brit, ea,
        SLTST: blk-dk gry, firm-mod hd, amor, gt, mod calc, SST:
        gry-dk gry, wl consol, v f, ang, p srt, cotd, slily calc
        cmt, no fluor

Isso deixa espaços no final das linhas que podem ser removidos b executando sed 's/ $//' .

A expressão 3,$s/(.{55} )/\n\t/g substituirá qualquer execução de 55 caracteres seguida por um espaço pelos mesmos 55 caracteres (e o espaço) seguido por uma nova linha e um recuo por uma tabulação. Isso se repete para todas as correspondências do padrão na linha.

    
por 05.09.2017 / 19:51
3

Com o padrão awk :

{ printf("%s\t", $1) }
{
    linelen = 8;  # assume 8 spaces for the first field

    for (i = 2; i <= NF; ++i) {
        wordlen = length($i);

        if (wordlen + linelen > 65) {
            # break output line since adding next word
            # would make it too long
            printf("\n\t");
            linelen = 8; # count tab as 8 spaces
        }

        if (i < NF) {
            printf("%s ", $i);
            linelen += wordlen + 1; # +1 for the space
        } else {
            printf("%s\n", $i);
        }
    }
}

Teste:

$ awk -f script.awk file.in
Depth   Description
(ft)    -
12370.0 LS: Mdst, blsh gry, sft, occ mod firm, crpxln, prly, arg,
        SLTST: blk, firm-mod hd, amor, gt, mod calc, CLST: lt
        gry-m gry, sft, amor, wxy
12400.0 LS: Mdst, blsh gry, mod firm, crpxln, chky, arg, SLTST:
        blk-dk gry, firm-mod hd, amor, gt, mod calc, CLST: lt
        gry-m gry, occ rdsh gry, mod firm, amor, wxy, tr CHK
12430.0 LS: Mdst, blsh gry, mod firm, crpxln, chky, arg, SLTST:
        blk-dk gry, firm-mod hd, amor, gt, mod calc, SH: blk-dk
        gry, mod firm, blky-plty, occ brit, wxy
12460.0 SH: blk-dk gry, mod firm, blky-plty, occ brit, ea, SLTST:
        blk-dk gry, firm-mod hd, amor, gt, mod calc, SST: gry-dk
        gry, wl consol, v f, ang, p srt, cotd, slily calc cmt, no
        fluor

A única desvantagem é que isso deixa espaços à direita na maioria das linhas de saída. Você pode desmembrá-los passando a saída embora sed 's/ $//' .

    
por 05.09.2017 / 18:47
0
Solução

awk :

awk 'NR<=2{ print }NR>2{ c=0; r=$1; 
            for(i=2;i<=NF;i++) { 
               if ((length(r) + length($i)) > (!c? 65:61)) { c++; printf "%s\n\t",r; r=$i } 
               else { r=r FS $i } if(i==NF) printf "%s",r } 
            print "" 
     }' file
  • NR<=2{ print } - imprima as duas primeiras linhas como é

  • r variable, contendo cada linha processada / formatada

A saída:

Depth   Description
(ft)    -
12370.0 LS: Mdst, blsh gry, sft, occ mod firm, crpxln, prly, arg,
    SLTST: blk, firm-mod hd, amor, gt, mod calc, CLST: lt gry-m
    gry, sft, amor, wxy
12400.0 LS: Mdst, blsh gry, mod firm, crpxln, chky, arg, SLTST:
    blk-dk gry, firm-mod hd, amor, gt, mod calc, CLST: lt gry-m
    gry, occ rdsh gry, mod firm, amor, wxy, tr CHK
12430.0 LS: Mdst, blsh gry, mod firm, crpxln, chky, arg, SLTST:
    blk-dk gry, firm-mod hd, amor, gt, mod calc, SH: blk-dk gry,
    mod firm, blky-plty, occ brit, wxy
12460.0 SH: blk-dk gry, mod firm, blky-plty, occ brit, ea, SLTST:
    blk-dk gry, firm-mod hd, amor, gt, mod calc, SST: gry-dk gry,
    wl consol, v f, ang, p srt, cotd, slily calc cmt, no fluor
    
por 05.09.2017 / 19:29