我有 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 列的实际纪元,因此该列可用于比较日期和排序。
我可以通过在 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 上执行 a 来找出我需要的行。
但是有没有办法使用命令行工具来做到这一点?
这种方法对我来说似乎太复杂了。
更新:
文件 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
,即两个文件中比每个人的最新记录更旧的所有记录:
$ 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