トップ回答者
同一ファイル内における、部分的重複のある行の処理について

質問
-
import-csvでCSVファイルを読み込んだオブジェクト $LIST があるとします。
-------CSVファイル中身----------------
timestamp,eventid,logonid
2015/03/12 13:24:01,4444,10000001
2015/03/13 13:24:02,4444,10000002
2015/03/14 13:24:03,4444,10000003
2015/03/15 13:24:04,5555,10000001
2015/03/16 13:24:05,5555,19999999
2015/03/17 13:24:06,5555,10000003
-------------------------------------
「$LISTを1行ずつ読み取り、その行の第3フィールドの値が後続の行の同じフィールドにあるかどうか」
を判定したいと思います。たとえば先頭の行の第3フィールドの値"10000001"と、別の行の第3フィールドの値とが一致していた場合、
比較元(先頭の行)にフィールドを追加し、比較先の行の第1フィールドの値を挿入することを考えております。
-------期待する出力----------------
timestamp,eventid,logonid,destination
2015/01/12 11:21:01,4444,10000001,2015/04/15 14:24:04
2015/02/13 12:22:02,4444,10000002,NotMatch!!
2015/03/14 13:23:03,4444,10000003,2015/06/17 16:21:06
2015/04/15 14:24:04,5555,10000001,2015/01/12 11:21:01
2015/05/16 15:25:05,5555,19999999,NotMatch!!
2015/06/17 16:21:06,5555,10000003,2015/03/14 13:23:03$LIST | group-object logonid
で、特定フィールドにおいて重複する行が存在するかどうか自体を確認することはできたのですが、
ここから突破口は無いものでしょうか。テキストファイル化して、ファイルを読み込んで1行ごとにファイルを再度読み込み・・・・という処理に頼らずにです。
よろしくおねがいいたします。
回答
-
こういう感じでしょうか?
ファイルの再読み込みこそしていないものの、オンメモリで二重ループしているので、レコード数が多い場合は遅くなると思います。
$list | select timestamp, eventid, logonid, @{ Name = "destination" Expression = { $ref = $_ $dif = $list | where {$_.eventid -ne $ref.eventid -and $_.logonid -eq $ref.logonid} if($null -eq $dif) { "NotMatch!!" } else { $dif.timestamp } } }
logonidが重複する場合は必ず2個で、それ以外は必ず1個という条件を加味してもうちょっとちゃんとアルゴリズムを考えれば、速度は改善できると思います。が、とりあえずはこれでどうでしょうか。
- 回答としてマーク Fuzitaman 2015年3月13日 9:52
すべての返信
-
こういう感じでしょうか?
ファイルの再読み込みこそしていないものの、オンメモリで二重ループしているので、レコード数が多い場合は遅くなると思います。
$list | select timestamp, eventid, logonid, @{ Name = "destination" Expression = { $ref = $_ $dif = $list | where {$_.eventid -ne $ref.eventid -and $_.logonid -eq $ref.logonid} if($null -eq $dif) { "NotMatch!!" } else { $dif.timestamp } } }
logonidが重複する場合は必ず2個で、それ以外は必ず1個という条件を加味してもうちょっとちゃんとアルゴリズムを考えれば、速度は改善できると思います。が、とりあえずはこれでどうでしょうか。
- 回答としてマーク Fuzitaman 2015年3月13日 9:52
-
こんばんは、
ログオンイベントとログオフイベントをユーザーごとに1行で表示するような事をやりたいのでしょうか。
以前、PCの起動・終了イベントを拾って1行で表示するスクリプトを作ったことがあります。
ロジック的には同じ様な気がしますので、もしご参考になれば。 -
それだと
2015/03/12 13:24:01,4444,10000001,2015/03/15 13:24:04
2015/03/15 13:24:04,5555,10000001,2015/03/12 13:24:01
2015/03/19 13:24:09,6666,10000001,2015/03/12 13:24:01のように初回行は2回目行の、それ以外は初回行の値になってしまいますよね? ですが質問文には
「$LISTを1行ずつ読み取り、その行の第3フィールドの値が後続の行の同じフィールドにあるかどうか」
とあり条件を満たせていないようにも思います。ですので正しいサンプルが重要と考えました。