pad um número com zeros

2

Eu preciso colocar 0 nos resultados do meu grep para que meu formato de script seja bom e eu não tenho ideia de como fazê-lo. aqui está o meu resultado grep:

261 : 261 = 0 | 1192 : 1184 = 8 | 
283 : 283 = 0 | 666 : 659 = 7 | 
267 : 267 = 0 | 631 : 620 = 11 |  
283 : 283 = 0 | 787 : 781 = 6 | 
278 : 279 = -1 | 963 : 957 = 6 |

eu quero mostrar algo assim:

261 : 261 = 000  | 1192 : 1184 = 0008 |   
283 : 283 =  000  | 0666 : 0659 = 0007 | 
267 : 267 =  000  | 0631 : 0620 = 0011 | 
283 : 283 =  000  | 0787 : 0781 = 0006 | 
278 : 279 = -001  | 0963 : 0957 = 0006 |

para obter esse resultado aqui está meu script:

count100='grep -ach "0100 $GivenBIN" $line'
count110='grep -ach "0110 $GivenBIN" $line'
filename='echo $line | awk -F"/" '{print $NF}''
echo -e "$filename     $count100 : $count110 = $ans1| $count220 : $count230 = $ans4 |" 
    
por afbr1201 29.05.2011 / 13:15

3 respostas

5

Com base no seu exemplo de entrada e saída, percebo que

  • colunas de números são sempre separadas por espaços em branco;
  • você deseja formatar cada coluna numérica para uma largura fixa conhecida;
  • você deseja o mesmo número de dígitos em cada linha de cada coluna;
  • uma coluna tem um sinal principal (espaço ou - ).

Isso se traduz no seguinte script awk, que aplica um formato printf a cada coluna numérica.

awk 'BEGIN {
    widths[1]=widths[3]=3;
    widths[5]=" 4";
    widths[7]=widths[9]=widths[11]=4
}
{
    for (i in widths) $i = sprintf("%0" widths[i] "d", $i);
    print
}'
    
por 29.05.2011 / 23:38
2

Isto é 4 expressões sed; longa mas simples
Ele adiciona um excesso de zeros à esquerda e, em seguida, reduz os números para 3 e 4 para os lados esquerdo e direito, respectivamente.
É difícil construir algo assim em uma única linha, mas é muito fácil quando é colocado sobre várias linhas, como mostrado na última seção do código ...
printf pode ser uma solução, mas não é tão simples quanto eu pensava, por causa dos números negativos, ie. sua exigência é que todos os números negativos tenham o mesmo número de dígitos que os números positivos.
... então estou lançando esse método sed porque funciona, mas pode haver soluções mais simples ...

sed -r -e "s/^([0-9]+)( : )([0-9]+)( = )(-)?([0-9]+)( )/0000/" -e "s/0*([0-9][0-9][0-9])( : )0*([0-9][0-9][0-9])( = )(-)?0*([0-9][0-9][0-9])( )//" -e "s/( )([0-9]+)( : )([0-9]+)( = )(-)?([0-9]+)( .)$/000000/" -e "s/( )0*([0-9][0-9][0-9][0-9])( : )0*([0-9][0-9][0-9][0-9])( = )(-)?0*([0-9][0-9][0-9][0-9])( .)$//" \
<<'EOF'
261 : 261 = 0 | 1192 : 1184 = 8 |
283 : 283 = 0 | 666 : 659 = 7 |
267 : 267 = 0 | 631 : 620 = 11 |
283 : 283 = 0 | 787 : 781 = 6 |
278 : 279 = -1 | 963 : 957 = 6 |
278 : 279 = -1 | 963 : 954 = -1 |
EOF

Aqui está a saída

261 : 261 = 000 | 1192 : 1184 = 0008 |
283 : 283 = 000 | 0666 : 0659 = 0007 |
267 : 267 = 000 | 0631 : 0620 = 0011 |
283 : 283 = 000 | 0787 : 0781 = 0006 |
278 : 279 = -001 | 0963 : 0957 = 0006 |
278 : 279 = -001 | 0963 : 0954 = -0001 |

Aqui está uma versão mais legível das expressões sed.

sed -r \
-e "s/^\
([0-9]+)( : )\
([0-9]+)( = )(-)?\
([0-9]+)( )\
/0000/" \
-e "s/\
0*([0-9][0-9][0-9])( : )\
0*([0-9][0-9][0-9])( = )(-)?\
0*([0-9][0-9][0-9])( )\
//" \
-e "s/( )\
([0-9]+)( : )\
([0-9]+)( = )(-)?\
([0-9]+)( .)$\
/000000/" \
-e "s/( )\
0*([0-9][0-9][0-9][0-9])( : )\
0*([0-9][0-9][0-9][0-9])( = )(-)?\
0*([0-9][0-9][0-9][0-9])( .)$\
//" \
    
por 29.05.2011 / 20:23
2

Você pode usar o printf comando: seu primeiro argumento é uma string de formato, seguida por outra argumentos que serão inseridos na string de formato, um por formato especificador.

O especificador de formato para imprimir uma string é %s ; um número inteiro é impresso com %d ; você pode, opcionalmente, especificar um número total de dígitos (por exemplo, 4) e uma percentagem de referência 0 para preenchimento com o formato %04d ; Se você quiser que um sinal seja sempre impresso, adicione um + após o caractere % , Se você quiser que um sinal seja impresso somente se o número for negativo, siga % por um caractere de espaço ( ). Além disso, você deve encerrar o format string com \n para imprimir um final de linha final como echo normalmente faz.

Veja a página do manual printf (3) a listagem completa.

Então, por exemplo:

count100=grep -ach "0100 $GivenBIN" $line
count110=grep -ach "0110 $GivenBIN" $line
filename=echo $line | awk -F"/" '{print $NF}'
printf '%s %d : %d = % 03d | %s : %d = %04d\n' "$filename" "$count100" "$count110" "$ans1" #...

imprimirá as linhas no formato desejado.

    
por 29.05.2011 / 17:12