Adiciona um número em um arquivo ASCII enorme

2

Histórico:

(1) Aqui está uma captura de tela de uma parte do meu arquivo ascii (acima de 600Mb):

(1.1) Aqui está uma parte do código:

 0, 0, 0, 0, 0, 0, 0, 0, 3.043678e-05, 3.661498e-05, 2.070347e-05, 
    2.47175e-05, 1.49877e-05, 3.031176e-05, 2.12128e-05, 2.817522e-05, 
    1.802658e-05, 7.192285e-06, 8.467806e-06, 2.047874e-05, 9.621194e-05, 
    4.467542e-05, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.000421869, 
    0.0003081213, 0.0001938675, 8.70334e-05, 0.0002973858, 0.0003385935, 
    8.763598e-05, 2.743326e-05, 0, 0.0001043894, 3.409237e-05, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2.503832e-05, 1.433673e-05, 2.557402e-05, 
    3.081098e-05, 4.044465e-05, 2.480817e-05, 2.681778e-05, 1.533265e-05, 
    2.3156e-05, 3.193812e-05, 5.325314e-05, 1.639066e-05, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 2.259782e-05, 0.0004197799, 2.65868e-05, 0.0002485498, 
    3.485129e-05, 2.454055e-05, 0.0002096856, 0.0001910835, 1.969936e-05, 
    2.974743e-05, 8.983165e-05, 0.0004263787, 0.0004444561, 0.000241368, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,

(2) Cada retângulo vermelho contém 74 elementos.

(3) Quero adicionar um número, por ex. 0,001, para cada uma das entradas diferentes de zero.

Meu pensamento:

(1) Fui informado pelo meu amigo que /perl pode ajudar a terminar essa tarefa, mas eu sou novo neste script de programação.

(2) Eu acho que a estratégia é ler cada um dos números e

(i) if it is a zero, then neglect it; or,
(ii) if it is non-zero, then add 0.001 to this number and replace this number.

(3) Minha preocupação é que:

Se /perl é capaz de ler um número em notação científica (ou seja, 1.303637e-05 é de fato igual a 0.00001303637)?

(4) Porque eu sou novo no unix, eu agradeço muito a você se você puder me dar o jeito de lidar com esse problema.

    
por nam 27.05.2015 / 19:35

2 respostas

2

Os seguintes itens devem funcionar:

perl -pe 's/([0-9.e-]+)/$1 == 0 ? $1 : .001 + $1/ge' < input.txt > output.txt
  • -p processa o arquivo linha por linha
  • s/patern/replacement/ é uma substituição.
  • [0-9.e-]+ corresponde a um ou mais dos caracteres fornecidos, ou seja, os números
  • () lembra cada número em $1
  • /g aplica a substituição globalmente, ou seja, quantas vezes forem necessárias para cada linha
  • /e avalia a substituição como código
  • condition ? then : else é o "operador ternário": se a condição for verdadeira ( $1 == 0 , ou seja, o número lembrado é igual a 0), retorna o número, caso contrário, ele adiciona .001 a ele.
por 27.05.2015 / 20:03
0

Se você não se importa, todos os números diferentes de zero estarão em formato de notação científica, tente:

perl -F, -anle '
  for (@F) {$_=sprintf " %e",$_+0.0001 if $_+0}
  print join ",", @F
' file
    
por 27.05.2015 / 20:09