입력하다
Time Value Flag
06:15:10 49.95 Actual
00:00:00 0.00 NoValue
06:22:50 49.94 Actual
06:23:00 49.93 Actual
06:23:10 49.93 Actual
06:23:20 49.93 Actual
06:23:30 49.93 Actual
06:24:40 49.92 Actual
00:00:00 0.00 NoValue
"NoValue"가 포함된 행을 바꿔야 합니다. 시간은 10초 단위로 마지막으로 녹화된 시간으로 대체됩니다(10초). 값은 마지막으로 녹화된 타임 스탬프로 대체됩니다. 실제 값으로 대체됩니다.
내 결과는 다음과 같이 표시됩니다.
Time Value Flag
06:15:10 49.95 Actual
06:15:20 49.95 Actual
06:22:50 49.94 Actual
06:23:00 49.93 Actual
06:23:10 49.93 Actual
06:23:20 49.93 Actual
06:23:30 49.93 Actual
06:24:40 49.92 Actual
06:24:50 49.92 Actual
답변1
awk -F'[: ]+' -v addSec=10 '
NR>1 && /Actual/{
sec=(($1*3600)+($2*60)+$3) +addSec;
prevTime=sprintf("%02d:%02d:%02d", sec/3600, sec%3600/60, sec%60) OFS $4 OFS $5;
}
/NoValue/{ $0=prevTime }1
' infile
답변2
이 시도:
catnova | tr -s "" | awk -F "[:]" -f val.awk
어디:
cat noval
06:15:10 49.95 Actual
00:00:00 0.00
06:22:50 49.94 Actual
06:23:00 49.93 Actual
06:23:10 49.93 Actual
06:23:20 49.93 Actual
06:23:30 49.93 Actual
06:24:40 49.92 Actual
00:00:00 0.00
그리고
cat val.awk
{
if($5=="") {
print g
}
else {
print $0
$3=$3+10
if ($3>59){
$3=$3-60
$2=$2+1
}
if ($2>59){
$2=$2-60
$1=$1+1
}
if(length($1)<2) {$1="0"$1}
if(length($2)<2) {$2="0"$2}
if(length($3)<2) {$3="0"$3}
g=$1":"$2":"$3" "$4" "$5
}
}
결과 :
06:15:10 49.95 Actual
06:15:20 49.95 Actual
06:22:50 49.94 Actual
06:23:00 49.93 Actual
06:23:10 49.93 Actual
06:23:20 49.93 Actual
06:23:30 49.93 Actual
06:24:40 49.92 Actual
06:24:50 49.92 Actual
참고: awk를 사용하여 콜론(:) 문자와 공백을 따라 각 줄을 나눕니다. 이를 통해 타임스탬프의 세 가지 구성 요소(열 1, 2, 3)에 액세스하여 잠재적으로 10을 더할 수 있습니다. 여러 공간을 하나로 압축하려면 tr을 사용합니다. awk의 F 플래그는 작업을 위해 콜론 및/또는 공백을 따라 줄을 끊도록 설정됩니다.
답변3
타임스탬프가 적용되는 날짜와 시간대를 모르고 날짜와 시간을 이해하는 유틸리티(예: 단순한 수학이 아님)를 사용하지 않으면 기존 시간에 10초를 더하여 새 시간을 결정할 수 없습니다. time is 아래 결과는 주어진 시간에 10초를 더하고 일광 절약 시간과 윤초의 영향을 받습니다.
입력 타임스탬프의 시작 날짜가 오늘이라고 가정하고 GNU awk를 사용하여 시간 함수를 처리합니다(DST를 처리하지만 POSIX 에포크 시간을 처리하는 모든 도구와 마찬가지로 윤초를 처리하지 않으므로 신경쓰지 않기를 바랍니다). 그것에 대해):
$ cat tst.awk
BEGIN {
OFS = " "
prevDate = (date=="" ? strftime("%Y %m %d") : date)
}
NR == 1 {
print
next
}
$3 == "NoValue" {
prevTime = gensub(/:/," ","g",prevLine[1])
prevSecs = mktime(prevDate " " prevTime)
currSecs = prevSecs + 10
prevDate = strftime("%Y %m %d",currSecs)
$1 = strftime("%T",currSecs)
$2 = prevLine[2]
$3 = prevLine[3]
}
{
print
split($0,prevLine)
}
$ awk -f tst.awk file
Time Value Flag
06:15:10 49.95 Actual
06:15:20 49.95 Actual
06:22:50 49.94 Actual
06:23:00 49.93 Actual
06:23:10 49.93 Actual
06:23:20 49.93 Actual
06:23:30 49.93 Actual
06:24:40 49.92 Actual
06:24:50 49.92 Actual
컴퓨터에 설정된 시간대와 다른 시간대에서 시간 계산을 적용하려면 위 작업을 수행하기 전에 셸 변수를 적절하게 설정하거나 및 TZ
호출에 UTC 플래그를 설정하세요.mktime()
strftime()
https://www.gnu.org/software/gawk/manual/gawk.html#Time-Functions.
오늘과 다른 시작 날짜를 사용하려면 awk -v date='2021 10 03' -f tst.awk file
원하는 YYYY MM DD
형식으로 날짜를 제공하는 스크립트를 호출하세요.
위의 내용에서는 처리 방법을 설명하지 않았기 때문에 타임스탬프가 항상 입력의 두 번째 줄에 채워지는 것으로 가정합니다.
@PhilipCouling이 주석(또는 다른 라이브러리)에서 지적했듯이 mktime()
DST가 끝날 때 전환 간격 동안 DST가 있는 시간대의 경우 날짜와 시간을 제공하는 것만으로는 에포크 이후 초를 안정적으로 반환할 수 없습니다(DST가 정상적으로 시작됨). ) ). 그들이 제공하는 예는 다음과 같습니다:
영국에서는 2022년 10월 30일 오전 01:30:00의 날짜/시간이 두 번 발생합니다. 이는 시계가 오전 2시에 도달하면 DST가 종료되고 시계가 오전 1시로 한 시간 뒤로 이동하기 때문입니다. 따라서 1:30은 DST가 끝나기 전에 한 번, DST가 끝난 후에 한 번 발생합니다. 파일에는 두 가지 중 어느 것을 설명하는지에 대한 정보가 포함되어 있지 않습니다. 파일은 DST가 종료되었는지 여부를 알려주지 않습니다.
답변4
사용행복하다(이전 Perl_6)
~$ raku -e 'my @init = [Z=>] lines[0].words, (DateTime.new("2024-01-01T00:00:00Z"), "0.00", "Initial");
put @init.map(*.key).join("\t");
for lines.map(*.words) -> ($t,$v,$f) {
if $f eq "NoValue" {
put join "\t", @init[0].value.hh-mm-ss, @init[1..*].map(*.value) andthen
@init[0] = @init[0].key => @init[0].value.later(:10seconds);
} else {
put join "\t", ($t,$v,$f) andthen
@init = [Z=>]
@init.map(*.key),
(DateTime.new("2024-01-01T" ~ $t ~ "Z").later(:10seconds),$v,$f)
}
};' file.txt
DateTime
Raku는 ISO 8601 개체가 내장된 Perl 제품군의 프로그래밍 언어입니다 . 위에서는 line[0]
초기 행( )을 헤더로 읽고 초기 값(초기 타임스탬프 포함)으로 키/값 쌍을 생성합니다 DateTime
. 축소 메타 연산자는 [Z=>]
뒤따르는 두 개의 목록을 키/값 쌍으로 함께 "압축"하여 배열 @init
(즉, 쌍의 배열)에 할당합니다. 헤더 행을 재구성하기 위해 즉시 출력 put
( 탭에 연결됨)됩니다.\t
여기에서 반복합니다 . 각 행은 블록 내에서 사용할 임시 변수에 할당되는 (즉, 열) lines
로 매핑되고 분류됩니다 .words
$t,$v,$f
$f
플래그 문자열이 "NoValue"와 같으면 해당eq
값이 출력됩니다.@init
그런 다음 타임스탬프를 추가합니다.$f
플래그ne
문자열이 "NoValue"와 같지 않으면 행($t,$v,$f)
의 값이 출력되고@init
배열은($t,$v,$f)
기본값/이전 값을 대체하는 새 값으로 업데이트됩니다. 그러면 타임스탬프가 증가됩니다.
Raku의 한 가지 장점은 DateTime
이러한 기능을 사용하여 later(:10seconds)
다음 "NoValue" 표시된 행의 보간을 위해 타임스탬프에 10초를 추가할 수 있다는 것입니다. 또한 hh-mm-ss
시간 부분만 반환할 수 있습니다( 2024-01-01
이 날짜는 결국 삭제되므로 임의의 날짜를 사용합니다).
입력 예(OP의 입력 예, NoValue
끝에 추가 줄 포함):
Time Value Flag
06:15:10 49.95 Actual
00:00:00 0.00 NoValue
06:22:50 49.94 Actual
06:23:00 49.93 Actual
06:23:10 49.93 Actual
06:23:20 49.93 Actual
06:23:30 49.93 Actual
06:24:40 49.92 Actual
00:00:00 0.00 NoValue
00:00:00 0.00 NoValue
예제 출력 1(위):
Time Value Flag
06:15:10 49.95 Actual
06:15:20 49.95 Actual
06:22:50 49.94 Actual
06:23:00 49.93 Actual
06:23:10 49.93 Actual
06:23:20 49.93 Actual
06:23:30 49.93 Actual
06:24:40 49.92 Actual
06:24:50 49.92 Actual
06:25:00 49.92 Actual
[위 설명: 샘플 입력 끝에 있는 여러 연속 "NoValue" 줄에 타임스탬프가 올바르게 증가했습니다.]
"NoValue" 초기 데이터 행 테스트: 확실히 하기 위해 아래에서 첫 번째( ) 데이터 행을 삭제하여 첫 번째 데이터 행 Actual
으로 만들 수 있습니다.00:00:00 0.00 NoValue
출력 2 예(위 입력 예에서 첫 번째 / Actual
데이터 행 제외):
Time Value Flag
00:00:00 0.00 Initial
06:22:50 49.94 Actual
06:23:00 49.93 Actual
06:23:10 49.93 Actual
06:23:20 49.93 Actual
06:23:30 49.93 Actual
06:24:40 49.92 Actual
06:24:50 49.92 Actual
06:25:00 49.92 Actual
위의 내용은 올바르게 처리하고 Initial
추정된(사람의) 값을 보고합니다.
https://www.iso.org/iso-8601-date-and-time-format.html
https://docs.raku.org/type/DateTime
https://raku.org