$ awk 'NR > 1 { print $0 - prev } { prev = $0 }' <file.dat
-0.043962
-0.020674
0.002742
-0.004449
0.011906
-0.026333
0.001461
0.011245
-0.002031
-0.009281
-0.006112
0.011811
-0.004837
Fazer isso em um loop de shell chamando bc
é complicado. O acima usa um script simples de awk
que lê os valores do arquivo um por um e para qualquer linha após o primeiro, ele imprime a diferença conforme você descreve.
O primeiro bloco, NR > 1 { print $0 - prev }
, imprime condicionalmente a diferença entre esta e a linha anterior se tivermos atingido a linha dois ou mais ( NR
é o número de registros lidos até o momento e um "registro" é de padrão uma linha).
O segundo bloco, { prev = $0 }
, define incondicionalmente prev
para o valor na linha atual.
Redirecione a saída para newfile.dat
para salvar o resultado:
$ awk 'NR > 1 { print $0 - prev } { prev = $0 }' <file.dat >newfile.dat
Relacionados:
Houve algumas menções sobre a lentidão de chamar bc
em um loop. O seguinte é uma maneira de usar uma única invocação de bc
para fazer a aritmética enquanto ainda lemos os dados em um loop de shell (eu não recomendaria realmente resolver esse problema dessa forma, e só estou mostrando aqui para pessoas interessado em coprocessos em bash
):
#!/bin/bash
coproc bc
{
read prev
while read number; do
printf '%f - %f\n' "$number" "$prev" >&"${COPROC[1]}"
prev=$number
read -u "${COPROC[0]}" result
printf '%f\n' "$result"
done
} <file.dat >newfile.dat
kill "$COPROC_PID"
O valor em ${COPROC[1]}
é o descritor de arquivo de entrada padrão de bc
, enquanto ${COPROC[0]}
é o descritor de arquivo de saída padrão de bc
.