GoPro 거리 데이터가 포함된 필드가 있습니다. 파일을 함께 연결해야 하지만 비디오 파일에는 설정된 지속 시간만 있기 때문에 각각의 새 csv 파일의 거리는 0에서 시작됩니다.
그렇다면 해당 숫자가 이전 레코드보다 작을 때 거리 필드를 어떻게 확인하여 그 이후의 모든 항목에 추가할 수 있습니까?
가능하다면 시간 필드를 0에서 0.05씩 증가시키는 방법은 무엇입니까?
나는 이 문제를 해결하기 위해 여러 포럼에서 awk 질문을 읽는 데 오랜 시간을 보냈지만 아직 성공하지 못했기 때문에 마침내 직접 질문을 하게 되었습니다.
이것은 파일을 연결하고 헤더를 유지하는 데 사용하는 awk 한 줄입니다.
awk '(NR == 1) || (FNR > 1)' *.csv > all.csv
아래에서는 각 새 워크시트에서 파일 끝의 숫자가 0으로 재설정되는 방법을 볼 수 있습니다.
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
다른 하나는 대신 루프와 배열을 사용합니다.
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
게시한 헤더 줄이 파일에 포함되어 있지 않다고 가정합니다( 달성하기 쉬울 것이라고 생각함).
두 번째는 모든 필드를 처리해야 한다고 가정합니다.
원하는 경우 AWK 스크립트에서 따옴표 안에 있지 않은 줄 바꿈을 포함하여 모든 공백을 생략할 수 있습니다(이 경우 따옴표/필수 공백이 전혀 없음). (세미콜론 중 일부를 생략하는 것도 가능하지만 그렇게 하고 싶지는 않습니다.)