Encontre o comprimento máximo de caracteres em um campo

3

Você pode me dizer como encontrar o comprimento máximo de caracteres em um determinado campo?

Por exemplo, com este arquivo de entrada:

s.no,name
1,ATM
35,money
63,back

O comprimento máximo no campo 1 é 2. Então, eu quero que a saída seja:

s.no,name
01,ATM
35,money
63,back

Aqui, adicionamos os zeros antes do número, se for < 2. Por favor me ajude.

    
por suneelbabu.etl 08.03.2014 / 15:57

2 respostas

4

Primeiro você precisa encontrar o tamanho máximo. Vírgula é o seu separador de campo e você precisa ignorar a primeira linha:

len=$(awk -F, 'BEGIN{mn=0;} NR>1{n=length($1);mn=mn>n?mn:n;}END{print mn}' test.txt)

Agora usamos printf para expandir o primeiro campo:

awk -F, 'NR==1{print $0};NR>1{ printf("%0'"$len"'d,",$1); for(i=2;i<=NF;i++)print($i); }' < test.txt

Observe que as aspas simples terminam antes de "$len" para inserir o comprimento do campo e, em seguida, elas continuam.

EDIT (obrigado @ dave_thompson_085 por uma solução mais elegante):

len=$(awk -F, 'BEGIN{mn=0} NR>1{n=length($1);mn=mn>n?mn:n;}END{print mn}' test.txt)
awk -F, -vOFS=, -vmn=$len 'NR>1{ $1=sprintf("%0*d",mn,$1)} 1' test.txt

em que o último 1 significa ação verdadeira e vazia significa {print} .

    
por 08.03.2014 / 16:13
2

Se você quiser apenas adicionar um 0 se a primeira coluna for um único caractere, isso será:

sed -e 's/^.,/0&/' input.txt

Nas linhas em que o segundo caractere é uma vírgula, o prefixo é 0.

Se o tamanho máximo de sua primeira coluna se torna 3 em vez de 2, você pode fazer assim:

sed -e 's/^.,/00&/' -e 's/^..,/0&/' input.txt

Ou, se você quiser deixar tudo isso dinâmico e preencher quantos zeros forem necessários, dependendo do maior valor da primeira coluna, você pode usar este awk :

awk -F, 'NR == 1; NR > 1 { data[NR] = $0; w1[NR] = length($1); if (length($1) > max) max = length($1) } END { for (i=2; i<= NR; ++i) { w = max - w1[i]; if (w > 0) printf "%0*d", w, 0; print data[i] } }' input.txt

A mesma coisa, mas expandida para várias linhas para facilitar a leitura, com comentários:

awk -F, '
NR == 1  # the first line is the header, just print it as it is
NR > 1 {
    data[NR] = $0        # save the line
    w1[NR] = length($1)  # save the width of 1st field
    if (length($1) > max) max = length($1)  # update max length
}
END {  # pass 2: now that we know max length, print the lines
    for (i = 2; i <= NR; ++i) {
        w = max - w1[i]  # calculate the zeros we need to prepend
        if (w > 0) printf "%0*d", w, 0  # print w zeros, if necessary
        print data[i]    # print the saved line
    }
}' input.txt
    
por 08.03.2014 / 16:11