GoPro距離データを含むフィールドがあります。ファイルを一緒にリンクする必要がありますが、ビデオファイルには設定された期間しかないため、各新しいcsvファイルの距離は0から始まります。
もしそうなら、その数が前のレコードよりも小さいときに距離フィールドをどのようにチェックして、それ以降のすべての項目に追加できますか?
可能であれば、時間フィールドを0から0.05ずつ増やす方法は?
私はこの問題を解決するためにいくつかのフォーラムでawkの質問を読むのに長い時間を費やしましたが、まだ成功していないので、ついに直接質問をしました。
これは、ファイルをリンクしてヘッダーを保持するために使用するawkの1行です。
awk '(NR == 1) || (FNR > 1)' *.csv > all.csv
以下では、各新しいワークシートでファイルの末尾の数字がゼロにリセットされる方法を示します。
CSV 1の終わり:
Time Feet Meters Miles Kilometers
676.65 9723.24067 2963.643756 1.841523 2.963644
676.7 9723.983124 2963.870056 1.841663 2.96387
676.75 9724.694981 2964.08703 1.841798 2.964087
676.8 9725.429621 2964.310948 1.841937 2.964311
676.85 9726.20625 2964.547665 1.842085 2.964548
676.9 9726.936465 2964.770235 1.842223 2.96477
676.95 9727.547469 2964.956469 1.842339 2.964956
CSV 2の始まり:
Time Feet Meters Miles Kilometers
0 0 0 0 0
0.05 0.687379 0.209513 0.00013 0.00021
0.1 1.469281 0.447837 0.000278 0.000448
0.15 2.223126 0.677609 0.000421 0.000678
0.2 2.965581 0.903909 0.000562 0.000904
0.25 3.736514 1.138889 0.000708 0.001139
0.3 4.530231 1.380814 0.000858 0.001381
出力は次のようになります。
Time Feet Meters Miles Kilometers
676.65 9723.24067 2963.643756 1.841523 2.963644
676.7 9723.983124 2963.870056 1.841663 2.96387
676.75 9724.694981 2964.08703 1.841798 2.964087
676.8 9725.429621 2964.310948 1.841937 2.964311
676.85 9726.20625 2964.547665 1.842085 2.964548
676.9 9726.936465 2964.770235 1.842223 2.96477
676.95 9727.547469 2964.956469 1.842339 2.964956
677 9727.547469 2964.956469 1.842339 2.964956
677.05 9728.234848 2965.165982 1.842469 2.965166
677.1 9729.01675 2965.404306 1.842617 2.965404
677.15 9729.770595 2965.634078 1.84276 2.965634
677.2 9730.51305 2965.860378 1.842901 2.96586
677.25 9731.283983 2966.095358 1.843047 2.966095
677.3 9732.0777 2966.337283 1.843197 2.966337
もう一度どんな助けにも感謝します。ありがとうございます。
答え1
場合に備えて、Pythonソリューションは次のとおりです。
import fileinput
from decimal import *
def main():
save_values = [Decimal(0.0) for n in range(5)]
last_values = save_values.copy()
header_shown = False
for line in fileinput.input():
line = line.strip()
if line == "":
continue
if line.startswith("Time"):
if not header_shown:
print(line)
header_shown = True
continue
(time, feet, meters, miles, kms) = [Decimal(x) for x in line.split()]
if time == 0.0:
save_values = last_values.copy()
continue
time += save_values[0]
feet += save_values[1]
meters += save_values[2]
miles += save_values[3]
kms += save_values[4]
print("{}\t{}\t{}\t{}\t{}".format(time, feet, meters, miles, kms))
last_values = [time, feet, meters, miles, kms]
if __name__ == "__main__":
main()
出力にはわずかに異なる出力があります。
676.95 9727.547469 2964.956469 1.842339 2.964956
677 9727.547469 2964.956469 1.842339 2.964956
しかし、正しい出力は次のようにすべきだと思います。
676.95 9727.547469 2964.956469 1.842339 2.964956
677.00 9728.234848 2965.165982 1.842469 2.965166
答え2
正確な回答を得るには、いくつかのサンプル行と現在のスクリプトを公開する必要があります。
数値が小さい場合は、比較する代わりにオフセット全体を保存し、オフセット[最初のファイルの場合は0]を追加して行を処理するときにオフセットを調整します。
例:
awk 'FNR==1&&ARGIND>1{distoffset=distnow}{$2+=distoffset;distnow=$2+$3;print $0;}'
フィールド2に距離があり、フィールド3に現在の項目の長さがあると仮定する。 (これは前のレコードの距離に追加する必要があります。そうでない場合は、ファイルの最初のレコードがファイルの最後のレコードと同じであると仮定します。古いファイルの距離。
他の質問に関しては、あなたが望むものが何であるかを理解していません。 0.05増分を追加することも問題ではありませんが、正確な要件を理解していない場合はどうすればよいか教えられません。
したがって、あなたが提供する追加情報を使用して、私の例をより完全にすることができます。
まず、より詳細なバージョンは次のとおりです。
rm -f all.csv
awk '
FNR==1 {
if (ARGIND>1) {
timeoffset = timenow + 0.05;
feetoffset = feetnow;
metersoffset = metersnow;
milesoffset = milesnow;
kmeteroffset = kmeternow;
} else {
print $0;
}
next;
}
FNR>1{
$1 += timeoffset; timenow = $1;
$2 += feetoffset; feetnow = $2;
$3 += metersoffset; metersnow = $3;
$4 += milesoffset; milesnow = $4;
$5 += kmeteroffset; kmeternow = $5;
print $0;
}
' *.csv > all.csv
もう1つは代わりにループと配列を使用します。
rm -f all.csv
awk '
FNR==1 {
if (ARGIND>1) {
for (cfn = 1; cfn <= NF; cfn++) {
offsetvals[cfn] = savedvals[cfn];
}
offsetvals[1] += 0.05;
} else {
print $0;
}
next;
}
FNR>1{
for (cfn = 1; cfn <= NF; cfn++) {
$cfn += offsetvals[cfn];
savedvals[cfn] = $cfn;
}
print $0;
}
' *.csv > all.csv
より一般的で、すべてのフィールドに適用されないか動的でなければならないファイルに再利用できるループを含むバージョンもあります。
rm -f all.csv
awk '
BEGIN {
procfields["tm"] = 1;
procfields["ft"] = 2; procfields["mt"] = 3;
procfields["ml"] = 4; procfields["km"] = 5;
}
FNR==1 {
if (ARGIND>1) {
for (fnname in procfields) {
cfn = procfields[fnname];
offsetvals[cfn] = savedvals[cfn];
};
offsetvals[procfields["tm"]] += 0.05;
} else {
print $0;
}
next;
}
FNR>1{
for (fnname in procfields) {
cfn = procfields[fnname];
$cfn += offsetvals[cfn];
savedvals[cfn] = $cfn;
};
print $0;
}
' *.csv > all.csv
公開したヘッダー行がファイルに含まれていないとします(達成しやすいと思います)。
2番目は、すべてのフィールドを処理する必要があると仮定します。
必要に応じて、AWKスクリプト内の引用符内にない改行を含むすべてのスペースを省略できます(この場合、引用符/必須スペースはまったくありません)。 (セミコロンの一部を省略することも可能ですが、そうしたくありません。)