Usando o awk:
awk -F'[(),]' '{ printf( "(%d %d)\n", $2 * 10000, $3 * 10000 ); }' file
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.
Usando o awk:
awk -F'[(),]' '{ printf( "(%d %d)\n", $2 * 10000, $3 * 10000 ); }' file
sed -e 's/,/ /' -e 's/\.\(..\)/0/g'
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 anFT
variable, it wouldn't need the special hack which applies whenFS
is equal to a single space; the default could be thatFS
is not set, andFK
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.
awk '{gsub(/\./,"")sub(/,/," "); print $1"00",$2}' file
(45679900 567898)
(56783300 673434)
Tags text-processing awk sed