Em python
re.sub(r"(?<=.)(?=(?:...)+$)", ",", stroke )
Para dividir um número por trigêmeos, por exemplo:
echo 123456789 | python -c 'import sys;import re; print re.sub(r"(?<=.)(?=(?:...)+$)", ",", sys.stdin.read());'
123,456,789
Como fazer o mesmo com o bash / awk?
bash
shell-script
awk
string
user2496
fonte
fonte
echo 123456789 | awk '$0=gensub(/(...)/,"\\1,","g")'
echo 123456789 | awk '$0=gensub(/(...)/,"\\1,","g"){sub(",$",""); print}'
sed
só funciona se o número tiver exatamente 9 dígitos. Oprintf
não funciona no zsh. Portanto, a segundased
resposta é provavelmente a melhor.echo 123456789 | awk '{printf ("%'\''d\n", $0)}'
(o que, evidentemente, nem sempre funciona no Linux, mas funciona bem no AIX e Solaris!?)bash
'sprintf
suportes praticamente tudo que você pode fazer naprintf
função Cprintf
de coreutils fará o mesmofonte
zsh
, post atualizado aqui .vsnprintf
. Em um sistema GNU / Linux, o glibc parece suportá-lo desde, pelo menos, 1995.export LC_NUMERIC="en_US"
se quiser forçar vírgulas.locale -a
. Eu tive que usaren_US.utf8
Você pode usar numfmt:
Ou:
Observe que o numfmt não é um utilitário POSIX, ele faz parte do GNU coreutils.
fonte
-d, --grouping
uma vez que as hifenizações duplas precisam de opções longas?--g
funciona bem para mim em vez de--grouping
, ou seja,numfmt --g 1234567890
enumfmt --grouping 1234567890
faz a mesma coisa. É um pequeno utilitário muito útil.produz:
Isso é feito dividindo a sequência de dígitos em 2 grupos, o grupo da direita com 3 dígitos, o grupo da esquerda com o que resta, mas com pelo menos um dígito. Então tudo é substituído pelos 2 grupos, separados por vírgula. Isso continua até a substituição falhar. As opções "wpe" são para listagem de erros, incluem a declaração dentro de um loop com uma impressão automática e usam o próximo argumento como o "programa" perl (consulte o comando perldoc perlrun para obter detalhes).
Muitas felicidades ... felicidades, drl
fonte
BASH
/AWK
alternativa para que ele não pode ter usadoPERL
antes. De qualquer forma, é melhor explicar o que o comando faz - especialmente para as frases de uso único.Com algumas
awk
implementações:"%'"'"'d\n"
é:"%
(aspas simples) (aspas duplas) (aspas simples) (aspas duplas) (aspas simples) d \ n"
Isso usará o separador de milhar configurado para o seu código do idioma (normalmente
,
em locais do inglês, espaço em francês,.
em espanhol / alemão ...). O mesmo que retornado porlocale thousands_sep
fonte
Um caso de uso comum para mim é modificar a saída de um pipeline de comandos para que os números decimais sejam impressos com mil separadores. Em vez de escrever uma função ou script, prefiro usar uma técnica que eu possa personalizar rapidamente para qualquer saída de um pipeline Unix.
Eu descobri
printf
(fornecido pela Awk) a maneira mais flexível e memorável de conseguir isso. O caractere de apóstrofo / aspas simples é especificado pelo POSIX como um modificador para formatar números decimais e tem a vantagem de reconhecer o código de idioma e não se restringir ao uso de caracteres de vírgula.Ao executar comandos do Awk a partir de um shell Unix, pode haver dificuldades para inserir um caractere de aspas simples dentro de uma string delimitada por aspas simples (para evitar a expansão de variáveis posicionais, por exemplo, shell
$1
). Nesse caso, acho que a maneira mais legível e confiável de inserir o caractere de aspas simples é inseri-lo como uma sequência de escape octal (começando com\0
).Exemplo:
Saída simulada de um pipeline mostrando quais diretórios estão usando mais espaço em disco:
Outras soluções estão listadas em Como escapar de uma única citação no awk .
Nota: conforme advertido em Imprimir uma cotação , é recomendável evitar o uso de seqüências de escape hexadecimais, pois elas não funcionam de maneira confiável em diferentes sistemas.
fonte
\047
.awk
ebash
tenha boas soluções internas, com base emprintf
, conforme descrito nas outras respostas. Mas primeirosed
.Pois
sed
, precisamos fazer isso "manualmente". A regra geral é que, se você tiver quatro dígitos consecutivos, seguidos por um não dígito (ou final de linha), uma vírgula deverá ser inserida entre o primeiro e o segundo dígito.Por exemplo,
irá imprimir
Obviamente, precisamos continuar repetindo o processo, para continuar adicionando vírgulas suficientes.
Em
sed
, ot
comando especifica um rótulo que será saltado para se o últimos///
comando for bem-sucedido. Por isso, defino um rótulo com:restart
, para que ele salte para trás.Aqui está uma demonstração do bash (em ideone ) que funciona com qualquer número de dígitos:
fonte
fonte
Se você está procurando números grandes, não consegui fazer as soluções acima funcionarem. Por exemplo, vamos obter um número realmente grande:
$ echo 2^512 |bc -l|tr -d -c [0-9] 13407807929942597099574024998205846127479365820592393377723561443721764030073546976801874298166903427690031858186486050853753882811946569946433649006084096
Nota: preciso
tr
remover a saída de nova linha com barra invertida do bc. Esse número é muito grande para ser tratado como um número flutuante ou de bit fixo no awk, e eu nem quero criar uma regexp grande o suficiente para dar conta de todos os dígitos no sed. Em vez disso, posso revertê-lo e colocar vírgulas entre grupos de três dígitos e depois revertê-lo:echo 2^512 |bc -l|tr -d -c [0-9] |rev |sed -e 's/\([0-9][0-9][0-9]\)/\1,/g' |rev 13,407,807,929,942,597,099,574,024,998,205,846,127,479,365,820,592,393,377,723,561,443,721,764,030,073,546,976,801,874,298,166,903,427,690,031,858,186,486,050,853,753,882,811,946,569,946,433,649,006,084,096
fonte
awk: run time error: improper conversion(number 1) in printf("%'d
.fonte
sed 's/^,//g'
.Eu também queria que a parte após o separador decimal fosse separada / espaçada corretamente, por isso escrevi esse script sed que usa algumas variáveis de shell para se ajustar às preferências regionais e pessoais. Também leva em consideração convenções diferentes para o número de dígitos agrupados :
fonte
Uma solução
bash
/awk
(conforme solicitado) que funciona independentemente do tamanho do número e usa,
independentemente dathousands_sep
configuração da localidade , e onde quer que os números estejam na entrada e evita adicionar o separador de milhar depois em1.12345
:Dá:
Em
awk
implementações comomawk
essa, não há suporte para os operadores de regex com intervalo, altere o regexp para/(^|[^.0123456789])[0123456789][0123456789][0123456789][0123456789]+/
fonte