Livre-se da casa decimal e cancele a vírgula

0

Eu tenho dados como este:

cat file
(4567.99,5678.98)
(5678.33,6734.34)

A saída que quero é:

(45679900 56789800)
(56783300 67343400)

Eu quero cancelar o decimal e deixá-lo com 8 dígitos e excluir o sinal de vírgula e deixá-lo entre os outros.

Usando o comando awk , como fazer isso? sed também está ok.

    
por heng960407 16.09.2016 / 04:42

4 respostas

4

Usando o awk:

awk -F'[(),]' '{ printf( "(%d %d)\n", $2 * 10000, $3 * 10000 ); }' file
    
por 16.09.2016 / 05:14
2

sed -e 's/,/ /' -e 's/\.\(..\)/0/g'

    
por 16.09.2016 / 05:12
1

TXR macro awk : podemos realmente fazer isso como operações digitadas: obter o dados como valores de ponto flutuante, reduza-os ao número inteiro mais próximo, multiplique por cem, converta para inteiro.

However, let us pause for a moment and reflect that this may be a bad idea if the values are so large that they cannot be truncated to the nearest integer; doing this text-wise will be correct for arbitrarily large values.

$ txr -e '(awk (:begin (set ft #/\d+.\d+/))
               ((mf tofloat floor toint (* 100))))'
(4567.99, 123.45, junk 3.1415, 1.0 ...) x
456700 12300 300 100

A variável ft é um novo recurso; Awk clássico não tem equivalente. Considerando que fs é como FS (separador de campo), ft significa "tokenize de campo": especifica um regex positivo que reconhece e extrai campos, ignorando o material não correspondente entre eles.

Ironically ft can directly express the semantics of the default field separator in Awk: trimming leading and trailing newlines and blanks from the record and separating on one or more newlines or blanks. That is precisely equivalent to simply positively recognizing the fields as tokens consisting of non-blanks! If Awk had an FT variable, it wouldn't need the special hack which applies when FS is equal to a single space; the default could be that FS is not set, and FK is set to the regex [ \t\n]+.

Usamos um simples ft que reconhece dígitos, um decimal obrigatório e dígitos obrigatórios. Sem sinal principal, sem peças opcionais.

A macro mf ("campos do mapa") coloca cada campo em um pipeline de operações. Em primeiro lugar, a função tofloat converte as cadeias em ponto flutuante. Então, floor trunca para o inteiro mais próximo, em direção ao infinito negativo. toint nos leva de volta ao inger e (* 100) denota a aplicação parcial de * a 100 : uma função que recebe argumentos adicionais e multiplica 100 pelo produto. Essa sintaxe parcial do aplicativo segue o fato de que mf arguments são implicitamente tratados como op syntax: o operador de aplicativo parcial explícito TXR Lisp.

Como mf retorna um resultado que não é nil , a ação padrão (prn) entra em ação para imprimir o rec atualizado, que é reconstituído catenando os campos atualizados com o padrão ofs que consiste em um caractere de espaço e a saída de um ors cujo padrão é nova linha.

Aqui está uma maneira de fazer isso numericamente, sem depender de matemática de ponto flutuante. Basicamente, podemos extrair os campos usando a mesma expressão regular, mas depois remover o ponto enquanto eles ainda são texto. Em seguida, vá para o inteiro e use truncar a divisão e multiplicação de inteiros:

 $ txr -e '(awk (:begin (set ft #/\d+.\d+/))
                ((mf (remq #\.) toint (trunc @1 100) (* 100))))'

Como os números inteiros podem ser arbitrariamente grandes nessa linguagem, essa solução não sofre problemas devido ao grande número dos números, mas minimiza o processamento do texto.

    
por 19.09.2016 / 23:16
1
awk '{gsub(/\./,"")sub(/,/," "); print $1"00",$2}' file
(45679900 567898)
(56783300 673434)
    
por 09.12.2018 / 12:41