다음 형식의 3열 데이터가 있습니다.
TIME MPID CPID
14:00:04.909 10048 370007
14:00:05.320 10048 370007
14:00:05.462 10048 370008
14:00:05.761 10048 370008
14:00:05.809 10048 370009
14:00:05.833 10048 370009
14:00:11.320 10048 370010
14:00:11.453 10048 370010
14:00:11.693 10048 370011
14:00:13.097 10048 370012
14:00:14.124 10048 370012
여기서 TIME 열은 HH:MM:SS.SSS 형식의 타임스탬프로 구성됩니다. MPID 및 CPID 열은 식별 번호입니다. 그 의미는 내 질문에 중요하지 않습니다. MPID 값도 데이터 세트에 존재하고 출력에 전파되어야 한다는 사실을 제외하고는 작동하지 않습니다.
내가 원하는 것은 CPID 값이 일치하는 행 쌍을 식별하고 해당 시간 간의 차이를 계산하는 것입니다. 예를 들어, 위의 예에는 CPID가 77846인 두 개의 행(세 번째 및 네 번째 행)이 있습니다. 해당 시간은 14:00:05.320과 14:00:05.589이므로 차이를 계산하고 싶습니다. 14: 00:04.909 - 14:00:05.320 = 00:00:00.589
또한 이 결과를 다음 형식으로 출력하고 싶습니다.
MPID 10051 CPID 77846 Total time difference: 589 mili seconds
주어진 CPID가 데이터 세트에 정확히 두 번 나타나지 않으면 이를 무시하고 싶습니다.
샘플 데이터가 주어진 경우 원하는 출력은 다음과 같아야 합니다.
MPID 10051 CPID 77845 Total time difference: 1400 milli seconds
MPID 10051 CPID 77846 Total time difference: 1300 milli seconds
MPID 10051 CPID 77847 Total time difference: 800 milli seconds
MPID 10051 CPID 77848 Total time difference: 1800 milli seconds
MPID 10051 CPID 77849 Total time difference: 1900 milli seconds
현재 사용되는 스크립트:
uniq -D -f 2 "${1}" |
while read a b c && read d e f ; do
g=$(( $(date -d $d +%s) - $(date -d $a +%s) ))
printf "MPID %s CPID %s Total time difference: %02i seconds\n" $b $c $g
done
출력은
MPID 10051 CPID 77845 Total time difference: 00 seconds
MPID 10051 CPID 77846 Total time difference: 03 seconds
MPID 10051 CPID 77847 Total time difference: 12 seconds
MPID 10051 CPID 77848 Total time difference: 15 seconds
MPID 10051 CPID 77849 Total time difference: 19 seconds
답변1
세 개의 동일한 행을 추가하여 해당 행이 거부되었음을 표시하고 "정확히 두 번" 요구 사항을 충족하여 CPID
샘플 데이터를 조정했습니다 . 또한 우리가 원하는 쌍인 370013
두 줄을 더 추가했습니다 .CPID
370014
TIME MPID CPID
14:00:04.909 10048 370007
14:00:05.320 10048 370007
14:00:05.462 10048 370008
14:00:05.761 10048 370008
14:00:05.809 10048 370009
14:00:05.833 10048 370009
14:00:11.320 10048 370010
14:00:11.453 10048 370010
14:00:11.693 10048 370011
14:00:13.097 10048 370012
14:00:14.124 10048 370012
14:00:14.189 10048 370013
14:00:14.320 10048 370013
14:00:15.020 10048 370013
14:00:16.123 10048 370014
14:00:16.790 10048 370014
달리기:
$ txr data.txr data
MPID 10048 CPID 370007 Total time difference: 411 mili seconds
MPID 10048 CPID 370008 Total time difference: 299 mili seconds
MPID 10048 CPID 370009 Total time difference: 24 mili seconds
MPID 10048 CPID 370010 Total time difference: 133 mili seconds
MPID 10048 CPID 370012 Total time difference: 1027 mili seconds
MPID 10048 CPID 370014 Total time difference: 667 mili seconds
단일 항목을 나타내지 않으며 370011
, 삼중 항목을 나타내지도 않습니다 370013
.
암호:
@(do (defun mk-time-ms (date ms)
(let ((tsec (time-parse-utc "%H:%M:%S" date)))
(+ (* tsec 1000) ms))))
TIME MPID CPID
@(repeat)
@d0.@ms0 @mpid @cpid
@d1.@ms1 @mpid @cpid
@ (collect :gap 0)
@extra @mpid @cpid
@ (end)
@ (do (unless (boundp 'extra)
(let ((t0 (mk-time-ms d0 (toint ms0)))
(t1 (mk-time-ms d1 (toint ms1))))
(put-line `MPID @mpid CPID @cpid Total time difference: @(- t1 t0) mili seconds`))))
@(end)
mk-time-ms
날짜를 정수(Unix 시대 이후의 시간)로 구문 분석하고 이를 밀리초 값과 결합하는 함수입니다. 초에 1000을 곱하고 밀리초를 더합니다.
헤더 줄을 그대로 일치시킵니다.
TIME MPID CPID
그런 다음 @(repeat)
게임이 시작됩니다. 동일한 cpid
( 및 )를 갖는 mpid
두 개의 연속 라인으로 시작하는 일련의 라인을 찾고 있습니다 . 추가함으로써 @(collect)
우리는 동일하거나 0개 이상의 행 mpid
과 일치하는 0개 이상의 행을 추가합니다 cpid
. 이들로부터 시간 목록을 extra
변수로 수집합니다. 각 일치 항목에 대해 extra
변수가 패턴 일치에 바인딩되지 않은 경우 이는 정확히 두 줄만 일치하고 추가 항목은 없음을 의미합니다. 이 경우 시간 차이를 계산하고 원하는 출력을 생성합니다.
@(repeat)
일치하는 항목이 없는 행을 건너뛰면 단일 항목이 처리됩니다. 다시 말하지만 @(collect)
, 기본적으로 일치하지 않는 줄은 건너뛰기 때문에 엄격해야 합니다 :gap 0
. 공백이 허용되지 않습니다. 그렇지 않으면 전체 데이터를 소비하고 @(repeat)
외부에는 아무것도 남기지 않습니다.
데이터에 실제로 삼중 중복이 없고 쌍 또는 싱글만 있는 경우 다음과 같을 수 있습니다.
@(do (defun mk-time-ms (date ms)
(let ((tsec (time-parse-utc "%H:%M:%S" date)))
(+ (* tsec 1000) ms))))
TIME MPID CPID
@(repeat)
@d0.@ms0 @mpid @cpid
@d1.@ms1 @mpid @cpid
@ (do (let ((t0 (mk-time-ms d0 (toint ms0)))
(t1 (mk-time-ms d1 (toint ms1))))
(put-line `MPID @mpid CPID @cpid Total time difference: @(- t1 t0) mili seconds`)))
@(end)
예제 데이터의 경우 이제 다음 출력이 포함됩니다.
MPID 10048 CPID 370013 Total time difference: 131 mili seconds
처음 두 370013
행이 비교되고 사용됩니다. 다음은 370013
싱글톤처럼 보이며 건너뜁니다. 이러한 두 가지 차이점을 포함하려면 @(trailer)
올바른 위치에 다음 줄을 추가하는 등 다음과 같이 수정하면 됩니다.
@(do (defun mk-time-ms (date ms)
(let ((tsec (time-parse-utc "%H:%M:%S" date)))
(+ (* tsec 1000) ms))))
TIME MPID CPID
@(repeat)
@d0.@ms0 @mpid @cpid
@ (trailer)
@d1.@ms1 @mpid @cpid
@ (do (let ((t0 (mk-time-ms d0 (toint ms0)))
(t1 (mk-time-ms d1 (toint ms1))))
(put-line `MPID @mpid CPID @cpid Total time difference: @(- t1 t0) mili seconds`)))
@(end)
이제 다음 줄이 출력에 나타납니다.
MPID 10048 CPID 370013 Total time difference: 131 mili seconds
MPID 10048 CPID 370013 Total time difference: 700 mili seconds
첫 번째와 두 번째 , 두 번째와 세 번째 370013
의 차이입니다 .
@(trailer)
뒤따르는 내용은 후행 컨텍스트라는 의미입니다. 즉, 일치하지만 소비되지는 않습니다. 따라서 @(repeat)
두 행이 일치하더라도 이제 하나의 행만 소비하므로 @(repeat)
두 행이 일치하고 시간 차이가 발생하더라도 다음 반복이 한 행 앞으로 이동하게 됩니다.