【Perl】ファイルリストからあるIDが最初に登場したファイルと最後に登場したファイルを得る
2016-03-23-2
[Programming][Perl]
ログの処理でよくやるやつを未来の自分のためにメモ。
ファイルリストからファイル中のあるIDが最初に登場したファイルと最後に登場したファイルを得る。つまりは、滞在期間・活動期間を取り出すタスク。
■コード (lifespan.pl):
■テストデータと実行例:
追記160901: 全面改訂。前の版はウェブ魚拓で。
ファイルリストからファイル中のあるIDが最初に登場したファイルと最後に登場したファイルを得る。つまりは、滞在期間・活動期間を取り出すタスク。
- 入力
- ファイルリストを入力とする
- ファイルは時間順に並べられている
- ファイルフォーマットはTSV形式で各行の第一カラムをIDとする
- 出力
- IDごとに初登場と最終出現のファイル名を出力
- ファイルリストの最後のファイルに出現している場合は今後も続く可能性があるのでフラグを立てる
■コード (lifespan.pl):
#!/usr/bin/env perl # -*- coding: utf-8 -*- use strict; use warnings; # ファイルリストを受け取る my @fns; while (<>) { chomp; next if not -e $_; push @fns, $_; } @fns = sort @fns; # 生成時間(=ファイル名)の順にソート my %items; for (my $i = 0; $i < @fns; $i++) { open(my $fh, "<", $fns[$i]) or die; my %cur; while (<$fh>) { chomp; my ($id, @c) = split(/\t/, $_); $items{$id}{first} ||= $fns[$i]; $items{$id}{last} = $fns[$i]; $items{$id}{content} = [$id, @c]; $cur{$id} = 1; } close($fh); } foreach my $id (sort keys %items) { my $first = $items{$id}{first}; # 初めてみたとき my $last = $items{$id}{last}; # 最後にみたとき my $alive = $last eq $fns[-1] ? 1 : 0; # まだ生きてる? print join(" ", $id, $alive, $first, $last, #@{$items{$id}{content}} )."\n"; }
■テストデータと実行例:
% ls -1 log/* log/20160315.txt log/20160316.txt log/20160317.txt log/20160318.txt log/20160319.txt log/20160320.txt log/20160321.txt % head log/*.txt ==> log/20160315.txt <== B0184BHSQU 1250 B012CIAZ34 1260 ==> log/20160316.txt <== B0184BHSQU 1250 B012CIAZ34 599 ==> log/20160317.txt <== B012CIAZ34 648 ==> log/20160318.txt <== B00KMRKDTY 702 ==> log/20160319.txt <== B00KMRKDTY 702 ==> log/20160320.txt <== B00KMRKDTY 702 ==> log/20160321.txt <== B00KMRKDTY 702 % ls log/*.txt |./lifespan.pl B00KMRKDTY 1 log/20160318.txt log/20160321.txt B012CIAZ34 0 log/20160315.txt log/20160317.txt B0184BHSQU 0 log/20160315.txt log/20160316.txt
追記160901: 全面改訂。前の版はウェブ魚拓で。