根据某列排序CSV?

cka*_*787 4 sorting perl

我确信我过去已经这样做过了,我忘记了一些小问题,但是如何在某个列上对CSV文件进行排序呢?我对有和没有第三方Perl模块的答案感兴趣.主要方法没有,因为我并不总是有权安装额外的模块.

示例数据:

name,25,female
name,24,male
name,27,female
name,21,male

在第二个数字列上排序后所需的最终结果:

name,21,male
name,24,male
name,25,female
name,27,female

Ala*_*avi 12

由于CSV是一种非常复杂的格式,因此最好使用为我们工作的模块.

以下是使用Text :: CSV模块的示例:

#!/usr/bin/env perl

use strict;
use warnings;

use constant AGE => 1;

use Text::CSV;

my $csv = Text::CSV->new();

my @rows;
while ( my $row_ref = $csv->getline( \*DATA ) ) {
    push @rows, $row_ref;
}

@rows = sort { $a->[AGE] <=> $b->[AGE] } @rows;

for my $row_ref (@rows) {
    $csv->combine(@$row_ref);
    print $csv->string(), "\n";
}

__DATA__
name,25,female
name,24,male
name,27,female
name,21,male
Run Code Online (Sandbox Code Playgroud)

  • 很好的答案.仅仅运行`split /,/`真的很诱人,但这对于Micro $ oft风格的CSV文件来说根本不够好.对于Unix冒号分隔的foocap文件,我认为它甚至不够好. (3认同)

Sim*_*ker 8

本着这种精神总是有另一种方法去做,请记住,简单的旧GNU排序可能就足够了.

$ sort -t, -k2 -n unsorted.txt
name,21,male
name,24,male
name,25,female
name,27,female
Run Code Online (Sandbox Code Playgroud)

命令行参数是:

-t, # use comma as the record separator
-k2 # sort on the second key (record) in the line
-n  # sort using numerical comparison (like using <=> instead of cmp in perl)
Run Code Online (Sandbox Code Playgroud)

如果你想要一个Perl解决方案,请将其包装在qx();-)中


Sin*_*nür 6

还有DBD :: CSV:

#!/usr/bin/perl

use strict; use warnings;
use DBI;

my $dbh = DBI->connect('dbi:CSV:', undef, undef, {
    RaiseError => 1,
    f_ext => '.csv',
    csv_tables => { test => { col_names => [qw' name age sex '] } },
});

my $sth = $dbh->prepare(q{
    SELECT name, age, sex FROM test ORDER BY age
});

$sth->execute;

while ( my @row = $sth->fetchrow_array ) {
    print join(',' => @row), "\n";
}

$sth->finish;
$dbh->disconnect;
Run Code Online (Sandbox Code Playgroud)

输出:

name,21,male
name,24,male
name,25,female
name,27,female