データテーブル内の一致するレコード間のペアごとの時間差(ミリ秒)を計算します。

データテーブル内の一致するレコード間のペアごとの時間差(ミリ秒)を計算します。

次の形式の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の2行(3行目と4行目)があります。その時間は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がデータセットに正確に2回表示されない場合は、それを無視したいと思います。

サンプルデータが与えられた場合、希望の出力は次のようになります。

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

3つの同じ行を追加して、その行が拒否されたことを示し、「正確に2回」の要件を満たすようにCPIDサンプルデータを調整しました。また、私たちが望むペアである3700132行を追加しました。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(および)のmpid2つの連続した行で始まる一連の行を探しています。追加することで、@(collect)同じ行またはゼロ行以上にmpid一致するゼロ行以上を追加しますcpid。これらから時刻リストをextra変数として収集します。各一致に対して、extra変数がパターン一致にバインドされていない場合、これは正確に2行だけ一致し、追加項目はないことを意味します。この場合、時間差を計算し、所望の出力を生成します。

@(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

最初の2370013行が比較され使用されます。以下は370013シングルトンのように見え、スキップされます。これらの2つの違いを含めるには、@(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

最初と2番目、2番目と3番目370013の違いです。

@(trailer)後続の内容は末尾のコンテキストという意味です。つまり、一致するが消費されません。したがって、@(repeat)2つの行が一致しても1行だけが消費されるため、@(repeat)2行が一致し、時間差が発生しても、次の反復が1行前に移動します。

関連情報