Adicione zeros à esquerda até que todas as linhas antes da vírgula consistam em nove caracteres e subseqüentemente insira um caractere a cada três dígitos usando sed

4

O objetivo é adicionar zeros à esquerda até que todas as linhas antes da vírgula consistam em nove caracteres e, subsequentemente, inserir um caractere a cada três dígitos usando sed .

Entrada

12345,1s4c3v6s3nh6
123456789,9h5vgbdx34dc
12,7h4f45dcvbgh
1234567,09klijnmh563

Resultado atual

[vagrant@localhost ~]$ sed -e 's/\([0-9]\{3\}\),/\/\//g' file
12/345/1s4c3v6s3nh6
123456/789/9h5vgbdx34dc
12,7h4f45dcvbgh
1234/567/09klijnmh563

Resultado esperado

000/012/345,1s4c3v6s3nh6
123/456/789,9h5vgbdx34dc
000/000/012,7h4f45dcvbgh
001/234/567,09klijnmh563

Nota:

  1. 12345 precisa se tornar 000012345 e 12 deve resultar em %código%. Em suma, a ênfase está na sequência numérica antes a vírgula.
  2. O formato das linhas é sempre %código%. Por exemplo, 000000012 nunca residirá no arquivo de entrada.

O problema é que o número de caracteres não pode ser equalizado usando sed. Como isso poderia ser feito?

    
por 030 18.09.2014 / 18:27

3 respostas

3

Se a sua entrada não tiver um número de sequência longo no segundo campo, tente:

$ sed -e 's|^[^,]*|#000000000&|;s|#[^,]*\(.\{9\}\),|,|;s|\([0-9]\{3\}\)|/|g;s|/\([^0-9]\)||;s|/$||' file
000/012/345,1s4c3v6s3nh6
123/456/789,9h5vgbdx34dc
000/000/012,7h4f45dcvbgh
001/234/567,09klijnmh563

Explicação

  • s|^[^,]*|#000000000&| : combinamos todas as coisas do início ao primeiro , , substituímos por um fabricante # e n números 0, em que n é o comprimento que queremos preencher.

  • s|#[^,]*\(.\{9\}\),|,| : combinamos todas as coisas do marcador com o primeiro , , mas mantemos os últimos 9 caracteres antes de , , descartamos o restante.

  • s|\([0-9]\{3\}\)|/|g : adicione uma / a cada 3 sequências de dígitos.

  • s|/\([^0-9]\)||;s|/$|| : se depois que / não for um número ou / estiver no final da linha, nós o removeremos.

ou mais fácil com perl :

$ perl -F',' -anle '
    $F[0] = sprintf "%09s", $F[0];
    $F[0] =~ s|.{3}|$&/|g;
    chop $F[0];
    print join ",",@F;
' file
000/012/345,1s4c3v6s3nh6
123/456/789,9h5vgbdx34dc
000/000/012,7h4f45dcvbgh
001/234/567,09klijnmh563
    
por 18.09.2014 / 19:08
3

Isso provavelmente pode ser feito em sed , mas está além do meu sed-fu. Aqui está uma solução diferente:

perl -F, -lane '$F[0]=sprintf("%09s",$F[0]);
                $F[0]=~s#(...)(?!$)#$1/#g;
                print "$F[0],$F[1]"' file

O -a divide cada linha de entrada em campos e a salva na matriz @F . O -F define o delimitador de campo ( , aqui). O -l remove as novas linhas finais e adiciona uma nova linha ao final de cada chamada de print e o n faz com que o arquivo de entrada seja lido linha por linha e o script fornecido por -e aplicado a cada linha.

O script em si faz 3 coisas. Primeiro, ele usa sprintf para adicionar 0 ao primeiro campo ( $F[0] ). Em seguida, substitui todos os conjuntos de três caracteres no primeiro campo (exceto aqueles no final: (?!$ ) ) with themselves followed by a / '. Finalmente, imprime o 1º campo agora modificado, uma vírgula e o segundo campo.

    
por 18.09.2014 / 19:15
1

Agora que a pergunta foi refinada, podemos simplificar a resposta de sed do Gnouc para

sed 's|^|000000000|;s|.*\(...\)\(...\)\(...,\)|//|' file

ou, se você quiser manter um sopro de uma solução geral,

sed 's|^|000000000|;s|.*\(.\{3\}\)\(.\{3\}\)\(.\{3\},\)|//|' file

Estes, como pelo menos algumas das outras respostas, suponha que há apenas uma vírgula em cada linha.

    
por 19.09.2014 / 01:17

Tags