如何使用Unix sort命令按日期对该CSV文件进行排序?

时间:2019-05-19 23:57:16

标签: csv sorting unix

我以前从未使用过UNIX,因此一直在使用它,因为我找不到Windows上的解决方案来对如此大的文件按日期对列表进行排序。

我正在尝试对包含1400万个条目的CSV文件进行排序(该文件为2gigs)。该文件是2013年1月发生的所有出租车交易。我想按日期对列表进行排序,以便只能选择第一周的数据。

我找到了https://www.gnu.org/software/coreutils/manual/html_node/sort-invocation.html,并且我一直在尝试编写一个可以满足我需要的命令。到目前为止,我尝试过的是

sort -t, -k 6n 8-trip_data_1.csv

那没用。

我想我要告诉它按第6列(提取日期时间)然后按该列的9,10索引排序,因为这就是整个文件的data列中将要更改的所有内容。我把一些桌子放在下面。

medallion,hack_license,vendor_id,rate_code,store_and_fwd_flag,pickup_datetime,dropoff_datetime,passenger_count,trip_time_in_secs,trip_distance,pickup_longitude,pickup_latitude,dropoff_longitude,dropoff_latitude
A6699B6310BFDF8D1EE42C12622D94FA,66C6E65E8D6476B8DDA075A01D63E78A,VTS,1,,2013-01-16 19:21:00,2013-01-16 19:35:00,2,840,1.71,-73.986603,40.739986,-73.99221,40.719715
B45D26A20BE724B0F752461C624233CB,B240D08915F9F593F219D9109127FF1A,VTS,1,,2013-01-16 19:26:00,2013-01-16 19:32:00,3,360,.67,-73.982338,40.768349,-73.981285,40.774017

2 个答案:

答案 0 :(得分:1)

您不需要n-的确适得其反。日期采用ISO 8601格式,并且按字母数字顺序进行排序。数字排序仅关注该领域的2013年部分;其余的不是单个数字的一​​部分。您也不必担心设置时间信息-只更改部分内容就无关紧要了。

您已经给了一个非常少的数据集,该数据集的拾音时间信息已经按顺序排列了,所以我们必须有所创新。标题信息不会按数字排序;您可以将其删除,也可以使其漂浮。为了显示对数据进行排序时可以进行排序,我指定了r(反向顺序)。这样会将标题数据放在顶部,并反转两行实际数据。

$ sort -t, -k6r data.file
medallion,hack_license,vendor_id,rate_code,store_and_fwd_flag,pickup_datetime,dropoff_datetime,passenger_count,trip_time_in_secs,trip_distance,pickup_longitude,pickup_latitude,dropoff_longitude,dropoff_latitude
B45D26A20BE724B0F752461C624233CB,B240D08915F9F593F219D9109127FF1A,VTS,1,,2013-01-16 19:26:00,2013-01-16 19:32:00,3,360,.67,-73.982338,40.768349,-73.981285,40.774017
A6699B6310BFDF8D1EE42C12622D94FA,66C6E65E8D6476B8DDA075A01D63E78A,VTS,1,,2013-01-16 19:21:00,2013-01-16 19:35:00,2,840,1.71,-73.986603,40.739986,-73.99221,40.719715
$

或者,按升序(标题位于末尾):

$ sort -t, -k6 data.file
A6699B6310BFDF8D1EE42C12622D94FA,66C6E65E8D6476B8DDA075A01D63E78A,VTS,1,,2013-01-16 19:21:00,2013-01-16 19:35:00,2,840,1.71,-73.986603,40.739986,-73.99221,40.719715
B45D26A20BE724B0F752461C624233CB,B240D08915F9F593F219D9109127FF1A,VTS,1,,2013-01-16 19:26:00,2013-01-16 19:32:00,3,360,.67,-73.982338,40.768349,-73.981285,40.774017
medallion,hack_license,vendor_id,rate_code,store_and_fwd_flag,pickup_datetime,dropoff_datetime,passenger_count,trip_time_in_secs,trip_distance,pickup_longitude,pickup_latitude,dropoff_longitude,dropoff_latitude
$

此外,您可以决定哪些日期相关,并修改此grep命令以选择第一周的正确日期,这会将数据大小减小到其原始大小的四分之一。

grep ',2013-01-0[1-7] [0-2][0-9]:[0-5][0-9]:[0-5][0-9],' data.file

查找日期范围为2013-01-01至2013-01-07(允许每天有任何时间)。如果愿意,可以在空格后省略正则表达式。如果数据有效,则不会有任何区别,但是正则表达式避免选择一些无效数据。显然,如果要运行第一周,则可以更改日期,例如,从第一个星期日到第一个星期六(2013年6月6日至12日,星期六):

grep -E ',2013-01-(0[6-9]|1[012]) [0-2][0-9]:[0-5][0-9]:[0-5][0-9],' data.file

然后您可以通过排序过程来运行此精简数据集。

将来,请提供5行左右的示例数据-可以更容易地证明哪些有效,哪些无效。

答案 1 :(得分:0)

我确定您不想删除标题,也不希望它“浮动”,因此请创建可执行文件sort_csv:

#!/usr/bin/perl

use strict;

sub my_cmp($$)
{
    my $a = shift;
    my $b = shift;
    return substr($a, 81, 8) cmp substr($b, 81, 8); # assuming seconds are always zero
}

print scalar (<>);
print sort my_cmp <>;

然后:

# Make it executable
chmod +x sort_csv

sort_csv <input.csv >sorted.csv
相关问题