同じ形式のファイルが2つあり、1列を除いてデータは同じです。
ファイル1の例示的な行:
"1/30/2017 11:14:55 AM",Valid customer,jim.smith,NY,1485771295
ファイル2の例示的な行:
"1/26/2017 8:02:01 PM",Valid customer,jim.smith,NY,1485457321
もちろん、このファイルには他の行もありますが、私が興味を持っている部分は次のとおりです。
ファイル2から同じエンティティに関連するすべての行、つまり$3
ファイル1の行の中から最新のタイムスタンプを持つ行を削除し、その行を維持したいと思います。休んでわかりました。
例の行では、列 1 の日付文字列に示すように、ファイル 1 の行がより最新であることがわかります。これで、行の最後の整数は列1の実際のepochであるため、その列を使用して日付を比較して並べ替えることができます。
次のようにPerlでスクリプトを書くだけです。
#!/usr/bin/perl
use strict;
use warnings;
my $file_a = "file1";
my $file_b = "file2";
open my $file_a_h, $file_a or die "Could not open $file_a";
sub timestamp_users {
my ($fh) = @_;
my %recs;
while ( my $line =<$fh> ) {
my @items = split ",", $line;
my $user = $items[3];
$recs{$user} = $items[5];
}
return \%recs;
}
my $file_a_recs = timestamp_users($file_a_h);
close $file_a_h;
open my $file_b_h, $file_b or die "Could not open $file_b";
my $file_b_recs = timestamp_users($file_b_h);
close $file_b_h;
my $count = 0;
while (my ($user, $last_time) = each %$file_b_recs) {
if(exists $file_a_recs->{$user} && $last_time >= $file_a_recs->{$user}) {
++$count;
`echo $user >> result.txt`;
}
}
print "count: $count\n";
この場合、ユーザーを出力し、grep -v
file_bで必要な行を見つけるために操作を実行する必要があります。
しかし、コマンドラインツールを使用してこれを行う方法はありますか?
このアプローチは私にとって複雑すぎるようです。
修正する:
ファイル1の例示的な行:
"1/30/2017 11:14:55 AM",Valid customer,jim.smith,NY,1485771295
"1/26/2017 5:06:11 AM",New customer,john.doe,CA,1485403571
"1/30/2017 4:14:30 AM",New customer,tim.jones,CO,1485746070
ファイル2の例示的な行:
"1/26/2017 8:02:01 PM",Valid customer,jim.smith,NY,1485457321
"1/30/2017 11:09:36 AM",New customer,tim.jones,CO,1485770976
"1/30/2017 11:14:03 AM",New customer,john.doe,CA,1485771243
"1/30/2017 11:13:53 AM",New customer,bill.smith,CA,1485771233
予想出力:
"1/30/2017 11:14:03 AM",New customer,john.doe,CA,1485771243
"1/30/2017 11:09:36 AM",New customer,tim.jones,CO,1485770976
"1/30/2017 11:13:53 AM",New customer,bill.smith,CA,1485771233
ベストアンサー1
両方のファイルの各行の最新バージョンを取得するには、次の手順を実行します。
$ cat file1 file2 | sort -t',' -k3,3 -k5,5nr | sort -t',' -u -k3,3 -o newest
これによりファイルがリンクされ、フィールド 3 と 5 のフィールドをソートキーとしてレコードがソートされます。これにより、各人の最新の履歴が最初に表示されるようにリンクされたファイルが並べ替えられます(最後の列のタイムスタンプのおかげで)。最後のソートでは、フィールド 3 をソートキーとして使用し、そのフィールドに基づいて一意にソートします。これにより、ファイル内のすべての人の最新の履歴のみが残りますnewest
。
次に、行の補完を作成しますnewest
。つまり、各人の最新の履歴よりも古い2つのファイルのすべての履歴を作成します。
$ cat file1 file2 | grep -v -F -x -f newest >older
行全体()で固定文字列一致()を実行しgrep
、()で一致しないすべての行を返します。これらの行はに保存されます。-F
-x
-v
newest
older
最後のステップは、ファイルfile2
内のすべての行を削除することですolder
。
$ grep -v -F -x -f older file2 >new-file2