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
Foi útil?

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.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top