Sed: estendendo uma cadeia de números para um certo número de dígitos preenchendo com zeros

5

Atualmente, estou tentando modificar uma sequência de caracteres alfanuméricos repetida por meio de pipetagem para sed. A área que estou interessado em modificar é um bloco de números, que eu gostaria de criar 8 caracteres, inserindo um número apropriado de zeros na frente dele. Por exemplo:

Entrada:

loremipsumdolorsit2367amet

Saída desejada:

loremipsumdolorsit00002367amet

É possível fazer isso com sed? Os blocos de números com os quais estou lidando têm menos de 8 caracteres, se isso ajudar. Não tenho certeza se o esta postagem ajuda. Obrigado antecipadamente!

Editar: há apenas um bloco de números em cada string.

    
por sourisse 16.10.2012 / 04:52

5 respostas

9

Isso pressupõe que há algum texto não numérico após o número:

echo "loremipsumdolorsit2367amet" \
| sed -r -e 's/[0-9]/0000000&/' -e 's/0*([0-9]{8}[^0-9])//'

Resultado: loremipsumdolorsit00002367amet

Isso não pressupõe que:

... | sed -r -e 's/[0-9]/0000000&/' -e 's/0*([0-9]{8}([^0-9]|$))//'

Estes usam os padrões ERE para sed. Muitas implementações de sed usam o sinalizador -r para especificar isso; alguns usam o -E flag; alguns usam ambos. Atualmente, a capacidade de usar padrões ERE no sed não faz parte do padrão POSIX, mas há rumores de adicioná-lo ao padrão. Não encontrei uma implementação moderna de sed que não tenha a capacidade de usar padrões ERE de uma forma ou de outra.

Em alguns casos, há coisas que você pode fazer usando padrões ERE que você não pode fazer usando os padrões de sed padrão (BREs). Consulte os comentários para esta resposta . Mas no presente caso, o uso de padrões ERE é apenas por conveniência. Como o sch diz em um comentário, você pode omitir o sinalizador -r (ou -E ) e simplesmente substituir o (...) por \(...\) e o {8} por \{8\} . Minha resposta original fez uso de + , que também não faz parte dos padrões BRE; mas na verdade isso não era necessário para a solução.

    
por 16.10.2012 / 05:22
9

com qualquer sed:

sed 's/[0-9]\{1,\}/0000000&/g;s/0*\([0-9]\{8,\}\)//g'
    
por 16.10.2012 / 09:18
5

Isso é possível com o perl:

perl -e 'my $a="loremipsumdolorsit2367amet"; $a =~ s/([0-9]+)/sprintf("%010d",$1)/e; print $a'

Tem:

loremipsumdolorsit0000002367amet

Para processar todas as linhas de entrada:

perl -pe 's/([0-9]+)/sprintf("%010d",$1)/e'
    
por 16.10.2012 / 05:05
2

Usando loops no sed:

echo loremipsumdolorsit2367amet | sed -r -e  :a -e 's/([^0-9])([0-9]{1,7}[^0-9])//;ta'

Guru.

    
por 16.10.2012 / 07:22
2

Também não é sed, mas aqui está uma alternativa awk levemente convoluta (GNU):

echo loremipsumdolorsit2367amet | awk '{gsub( /[0-9]+/, sprintf( "%08d", gensub(/[^0-9]/, "","g"))); print}' 
loremipsumdolorsit00002367amet
    
por 16.10.2012 / 05:53

Tags