嗨,我是新手fir perl脚本编写者,我需要一个帮助来实现用于对基于CSV文件标题的列值进行排序的逻辑。
示例:
S.NO,NAME,S2,S5,S3,S4,S1
1,aaaa,88,99,77,55,66
2,bbbb,66,77,88,99,55
3,cccc,55,44,77,88,66
4,dddd,77,55,66,88,99
现在我要按以下方式对该文件进行排序。
s.no,s2,s4,s5,s1,s0,name =>这就是我想要的,因为我定义了s.no,name,s1,s2,s3,s4,s5之类的标头顺序,它们分别是整个列的值也应该根据标题交换而改变,如何做到这一点……?
这是必需的输出,就像下面的波纹管一样
S.NO,NAME,S1,S2,S3,S4,S5 1,aaaaaaa,66,88,77,55,99 2,bbbbbbb,55,66,88,77,99 3,ccccccc,66,55,77,88,44 4,ddddddd,99,77,66,88,55
或我想要的列标题顺序,如下所示。
S.NO,NAME,S5,S4,S3,S2,S1->按照我的要求,我需要重新排序我的列标题,并且它也是相应的列值。
#!/usr/bin/perl
use strict;
use warnings;
use Text::CSV;
my $file = 'a1.csv';
my $size = 3;
my @files;
my $csv = Text::CSV->new ({ binary => 1, auto_diag => 1, sep_char => ';' });
open my $in, "<:encoding(utf8)", $file or die "$file: $!";
while (my $row = $csv->getline($in)) {
if (not @files) {
my $file_counter = int @$row / $size;
$file_counter++ if @$row % $size;
for my $i (1 .. $file_counter) {
my $outfile = "output$i.csv";
open my $out, ">:encoding(utf8)", $outfile or die "$outfile: $!";
push @files, $out;
}
}
my @fields = @$row;
foreach my $i (0 .. $#files) {
my $from = $i*$size;
my $to = $i*$size+$size-1;
$to = $to <= $#fields ? $to : $#fields;
my @data = @fields[$from .. $to];
$csv->print($files[$i], \@data);
print {$files[$i]} "\n";
}
}
答案 0 :(得分:3)
#!/usr/bin/perl
use strict;
use warnings;
use autodie;
use Text::CSV qw();
my @headers = qw(s.no name s1 s2 s3 s4 s5);
my $csv_in = Text::CSV->new({binary => 1, auto_diag => 1});
my $csv_out = Text::CSV->new({binary => 1, auto_diag => 1});
open my $in, '<:encoding(UTF-8)', 'a1.csv';
open my $out, '>:encoding(UTF-8)', 'output1.csv';
$csv_in->header($in);
$csv_out->say($out, [@headers]);
while (my $row = $csv_in->getline_hr($in)) {
$csv_out->say($out, [$row->@{@headers}]);
}
答案 1 :(得分:2)
便捷的Text::AutoCSV模块使您可以将单列排列顺序重新排列:
$ perl -MText::AutoCSV -e 'Text::AutoCSV->new(in_file=>"in.csv",out_file=>"out.csv",out_fields=>["SNO","NAME","S1","S2","S3","S5"])->write()'
$ cat out.csv
s.no,name,s1,s2,s3,s5
1,aaaa,66,55,77,99
2,bbbb,55,99,88,77
3,cccc,66,88,77,44
4,dddd,99,88,66,55
我不确定您实际想要的字段顺序是什么,因为您有两个字段,并且两个字段都包含示例输入文件中没有的列(它有两个s2列;其中一个应该是s4吗?),但您应该明白这一点。列名必须全部使用大写字母,并带有特殊字符。删除,但实际名称用于输出。
答案 2 :(得分:0)
my $eix = "001"; $csv_in->header ($in, munge_column_names => sub { s/^$/"E".$eix++/er/; });