我有一个巨大的csv文件(100,000条记录),其中包含如下数据:
Col1 Col2 Date & Time
a xyz Oct 31 2014 09:01
b xyz Dec 12 2013 08:15
a xyz Oct 30 2014 07:01
c xyz Dec 26 2013 08:39
a xyz Nov 12 2014 08:25
c xyz Dec 12 2013 08:10
b xyz Dec 12 2013 09:21
我需要删除重复项并仅保留最新的数据(基于第三列 - 日期和时间)。所以输出应该像
Col1 Col2 Date & Time
a xyz Nov 12 2014 08:25
b xyz Dec 12 2013 09:21
c xyz Dec 26 2013 08:39
我首先尝试对文件进行排序,然后删除重复项,但是这个巨大的csv文件失败了。有人可以帮忙吗?
P.S。在col1中,数据可以多次来自a-z。这只是一个样本。
答案 0 :(得分:0)
让我们尝试一下:
while IFS="," read -r a b c
do
printf "%s %s %s %d\n" "$a" "$b" "$c" $(date -d"$c" +"%s")
done < file | \
awk '{it=$NF; NF--
if (max[$1]<it) {max[$1]=it; res[$1]=$0}}
END {for (i in max) print res[i]}'
这将存储数组max[]
中的最大日期,该数据由临时的最后一个字段索引,该字段表示自1970年1月1日以来的秒数(先前使用while read
bash创建的)。处理整个块后,在END{}
中打印结果。
它返回:
a xyz Nov 12 2014 08:25
b xyz Dec 12 2013 09:21
c xyz Dec 26 2013 08:39
如果碰巧以逗号分隔,请使用:
$ while IFS="," read -r a b c; do printf "%s,%s,%s,%d\n" "$a" "$b" "$c" $(date -d"$c" +"%s"); done < a | awk 'BEGIN{FS=OFS=","} {it=$NF; NF--
if (max[$1]<it) {max[$1]=it; res[$1]=$0}}
END {for (i in max) print res[i]}'
a,xyz,Nov 12 2014 08:25
b,xyz,Dec 12 2013 09:21
c,xyz,Dec 26 2013 08:39
答案 1 :(得分:0)
您的流程有3个步骤。 第一:
提取关键字段。 (我用perl和split)。
将日期解析为数字格式。你可以做某种ISO风格,例如2014-12-26 08:39或将其变成Unix'时代'时代。 (如果它是CSV,如果你真的想要,你可能会通过Excel进行处理。)
运行您的输入,丢弃任何“旧”值。
所以考虑到这一点 - 假设因为你说'CSV',你的意思是它实际上是逗号分隔的值。
#!/usr/bin/perl
use strict;
use warnings;
use Time::Piece;
my %most_recent;
my $header = <DATA>;
while ( my $line = <DATA> ) {
chomp $line;
my ( $col1, $col2, $date_and_time ) = split( /,\s*/, $line, 3 );
$date_and_time =~ s/\s+$//g;
my $time = Time::Piece -> new -> strptime( $date_and_time, "%b %d %Y %H:%M" );
if ( not defined $most_recent{$col1}{$col2}
or $most_recent{$col1}{$col2} < $time )
{
$most_recent{$col1}{$col2} = $time;
}
}
print "Most recent:\n";
foreach my $col1 ( keys %most_recent ) {
foreach my $col2 ( keys %{ $most_recent{$col1} } ) {
print "$col1, $col2, $most_recent{$col1}{$col2}, \n";
}
}
__DATA__
Col1, Col2, Date & Time
a, xyz, Oct 31 2014 09:01
b, xyz, Dec 12 2013 08:15
a, xyz, Oct 30 2014 07:01
c, xyz, Dec 26 2013 08:39
a, xyz, Nov 12 2014 08:25
c, xyz, Dec 12 2013 08:10
b, xyz, Dec 12 2013 09:21
这将 - 对于Col1
和Col2
的每个唯一配对,选择该对的最新时间戳。
注意 - 在各个步骤(拆分和时间戳解析)中,空格被丢弃。