Imprimindo mil carros alegóricos separados com GAWK
-
09-09-2019 - |
Pergunta
I deve processar algum arquivo enorme com gawk. Meu principal problema é que eu tenho que imprimir alguns carros alegóricos usando separadores de milhar. Ex .: 10000
deve aparecer como 10.000
e 10000,01
como 10.000,01
na saída.
I (e Google) venha com essa função, mas esta falha para carros alegóricos:
function commas(n) {
gsub(/,/,"",n)
point = index(n,".") - 1
if (point < 0) point = length(n)
while (point > 3) {
point -= 3
n = substr(n,1,point)"."substr(n,point + 1)
}
sub(/-\./,"-",n)
return d n
}
Mas ele falha com carros alegóricos.
Agora eu estou pensando de dividir a entrada para um inteiro e um <1 parte, em seguida, depois de formatar o inteiro colando-os novamente, mas não há uma maneira melhor de fazer isso?
Disclaimer:
- Eu não sou um programador
- Eu sei que através de algum env SHELL. variáveis ??os mil separadores pode ser definido, mas deve estar trabalhando em diferentes ambientes com diferentes lang e / ou configurações locais.
- Inglês é a minha segunda língua, desculpe se eu estou usando-o incorretamente
Solução
Ele falha com flutuadores porque você está passando em números tipo europeu (1.000.000,25 para um milhão e um quarto). A função que você tenha dado deve funcionar se você acabou de mudar ao longo vírgulas e pontos. Eu testar a versão atual primeiro com 1.000.000,25 para ver se ele funciona com números não-europeus.
O script awk seguinte pode ser chamado com "echo 1 | awk -f xx.gawk"
e ele vai mostrar tanto a versão "normal" e europeia em acção. Ele produz:
123,456,789.1234
123.456.789,1234
Obviamente, você está interessado apenas nas funções, código do mundo real usaria o fluxo de entrada para passar valores para as funções, não uma string fixa.
function commas(n) {
gsub(/,/,"",n)
point = index(n,".") - 1
if (point < 0) point = length(n)
while (point > 3) {
point -= 3
n = substr(n,1,point)","substr(n,point + 1)
}
return n
}
function commaseuro(n) {
gsub(/\./,"",n)
point = index(n,",") - 1
if (point < 0) point = length(n)
while (point > 3) {
point -= 3
n = substr(n,1,point)"."substr(n,point + 1)
}
return n
}
{ print commas("1234,56789.1234") "\n" commaseuro("12.3456789,1234") }
As funções são idênticas, exceto na sua manipulação de vírgulas e pontos. Vamos chamá-los de separadores e decimais na seguinte descrição:
- gsub remove todos os separadores existentes, uma vez que vai ser colocá-los de volta.
- achados ponto onde o decimal é uma vez que é o nosso ponto de partida.
- Se não há decimal, IF-declaração começa no final.
- nós loop while há mais de três caracteres para a esquerda.
- dentro do ciclo, que ajustar a posição para a inserção de um separador, e inseri-lo.
- Uma vez que o ciclo está terminado, nós devolver o valor ajustado.
Outras dicas
Para ir com do Pax resposta :
Leia a secção "conversão" do GNU awk Manual , que fala explicitamente sobre o efeito da variável de ambiente LOCALE
sobre a representação de cadeia de tipos numéricos.