ファイルの行を繰り返し、現在の行から前の行を減算します。

ファイルの行を繰り返し、現在の行から前の行を減算します。

数値を含むファイルがあります。

$ cat file.dat
0.092593
0.048631
0.027957
0.030699
0.026250
0.038156
0.011823
0.013284
0.024529
0.022498
0.013217
0.007105
0.018916
0.014079

現在の行と前の行の違いを含む新しいファイルを作成したいと思います。予想される出力は次のようになります。

$ cat newfile.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

簡単だと思うので、このコードで始めました。

f="myfile.dat"    
while read line; do
    curr=$line
    prev=

    bc <<< "$line - $prev" >> newfile.dat
done < $f

しかし、私はファイルの前の行にアクセスする方法がわからないことにすぐに気づきました。最初の行を読むときにマイナスがないことを考慮する必要があるようです。進行方法のご案内をいただきありがとうございます!

ベストアンサー1

$ 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

シェルループ呼び出し内でこれを行うのはbc面倒です。上記は、awkファイルの値を1つずつ読み、最初の行以降のすべての行について説明する違いを印刷する単純なスクリプトを使用しています。

NR > 1 { print $0 - prev }2行目以上(NRこれまでに読んだレコード数、デフォルトでは「レコード」は1行)に達すると、最初のブロックは条件付きでこの行と前の行の違いを印刷します。

2番目のブロック{ prev = $0 }は無条件prevに現在の行の値に設定されます。

newfile.dat結果を保存するには、出力をリダイレクトします。

$ awk 'NR > 1 { print $0 - prev } { prev = $0 }' <file.dat >newfile.dat

関連:


誰かがbcループ呼び出しが遅いと述べました。以下は、シェルループからデータを読み取るときに単一の呼び出しを使用して算術を実行する方法です。bc(私は実際にこの方法で問題を解決することをお勧めしません。coに興味がある人のためにここに表示しています。) - プロセスは次のとおりです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"

の値${COPROC[1]}は標準入力ファイル記述子ですが、標準出力ファイル記述子ではありませんbc${COPROC[0]}bc

おすすめ記事