Perl CSV解析与标题访问-标题位于第3行,仅部分行而非所有行

zbq4xfa0  于 2022-11-15  发布在  Perl
关注(0)|答案(4)|浏览(113)

我正在尝试解析一个给定的CSV文件,流在定期的基础上。
我的要求是通过列名(标题)访问数据。列名不在第1行中。列名在第2行中。CSV确实有100行,但我只需要导入2个数据行。分隔符是一个制表符。
下面的脚本适用于第1行的标题和文件中的所有行,我未能将其修改为第2行的标题,并且仅使用2行或多行。
脚本:

#!/usr/bin/perl
use strict;
use warnings;
use Tie::Handle::CSV;
use Data::Dumper;



my $file = "data.csv";
my $fh = Tie::Handle::CSV->new ($file, header => 1, sep_char => "\t");
my $hfh = Tie::Handle::CSV->new ($file, header => 0, sep_char => "\t");

my $line = <$hfh>;
my $myheader;

while (my $csv_line = <$fh>)
{

        foreach(@{$line}) 
        {
                if ( $_ ne "" )
                {
                        print $_ . "=" .   $csv_line->{$_} . "\n" ;
                }
        }

}

Data.csv可能如下所示:

This is a silly sentence on the first line
Name    GivenName   Birthdate   Number
Meier   hans    18.03.1999  1
Frank   Thomas  27.1.1974   2
Karl    Franz   1.1.2000    3
Here could be something silly again

谢谢你的提示。
顺祝商祺

5hcedyr0

5hcedyr01#

使用Text::CSV_XS代替Tie::Handle::CSV(这取决于模块,因此您已经安装了它),读取并丢弃第一行,使用第二行设置列名,然后读取其余数据:

#!/usr/bin/env perl
use warnings;
use strict;
use feature qw/say/;
use Text::CSV_XS;

my $csv = Text::CSV_XS->new({ sep => ",", # Using CSV because TSV doesn't play well with SO formatting
                              binary => 1});

# Read and discard the first line
$_ = <DATA>;

# Use the next line as the header and set column names
$csv->column_names($csv->getline(*DATA));

# Read some rows and access columns by name instead of position
my $nr = 0;
while (my $record = $csv->getline_hr(*DATA)) {
    last if ++$nr == 4;
    say "Row $nr: $record->{GivenName} was born on $record->{Birthdate}";
}

__DATA__
This is a silly sentence on the first line
Name,GivenName,Birthdate,Number
Meier,hans,18.03.1999,1
Frank,Thomas,27.1.1974,2
Karl,Franz,1.1.2000,3
Here could be something silly again
djmepvbi

djmepvbi2#

Tie::Handle::CSV接受文件句柄而不是文件名。在将文件句柄传递给Tie::Handle::CSV之前,您可以通过阅读第一行来跳过第一行:

use strict;
use warnings;
use Tie::Handle::CSV;
use Data::Dumper;

my $file = "data.csv";

open (my $infile, '<',$file) or die "can't open file $file: $!\n";
<$infile>; # skip first line
my $hfh = Tie::Handle::CSV->new ($infile, header => 1, sep_char => "\t");

my @csv;
my $num_lines = 3;
while ($num_lines--){
    my $line = <$hfh>;
    push @csv, $line;
}
print Dumper \@csv;
sgtfey8w

sgtfey8w3#

多亏了你们俩。
更详细地阐明我的要求。
原始数据文件可能有100个列,这些列的动态名称对我来说是未知的。我将从其他服务创建列/属性列表,此脚本应提供这些列的数据内容。
请求是在数据方面的例子:请提供前25行的所有姓名和所有出生日期。下一个请求可以是前10行的所有姓名和Givenames。
这意味着从100列的内容中,我必须提供两列、四列、五列的内容。
我使用的输出(foreach),只是为了测试通过ColumName访问行的内容。
我混淆了您的解决方案,并选择了Tie::Handle::CSV。
目前我必须使用两个文件句柄-也许你有一个更有效的提示。

#!/usr/bin/perl
use strict;
use warnings;
use Tie::Handle::CSV;
use Data::Dumper;



my $file = "data.csv";

open (my $infile, '<',$file) or die "can't open file $file: $!\n";
open (my $secfile, '<',$file) or die "can't open file $file: $!\n";
<$infile>; # skip first line
<$secfile>;

my $fh = Tie::Handle::CSV->new ($secfile, header => 1, sep_char => "\t");
my $hfh = Tie::Handle::CSV->new ($infile, header => 0, sep_char => "\t");

my $line = <$hfh>;

my $numberoflines = 2 ;

while ($numberoflines-- )
{
        my $csv_line = <$fh> ;

        foreach(@{$line})
        {
                if ( $_ ne "" )
                {
                        print $_ . "=" .   $csv_line->{$_} . "\n" ;
                }
        }

}
z0qdvdin

z0qdvdin4#

谢谢,用“keys %$csv_line”运行它。我没有使用,因为缺少knowlegde。- )

#!/usr/bin/perl
use strict;
use warnings;
use Tie::Handle::CSV;

my $file = "data.csv";

open (my $secfile, '<',$file) or die "can't open file $file: $!\n";
<$secfile>;
my $fh = Tie::Handle::CSV->new ($secfile, header => 1, sep_char => "\t");

my $numberoflines = 3 ;

while ($numberoflines-- )
{
        my $csv_line = <$fh> ;
        my @Columns = keys %{ $csv_line } ;
        foreach (@Columns )      
        {
                if ( $_ ne "" )
                {
                        print $_ . "=" .   $csv_line->{$_} . "\n" ;
                }
        }
        print "-----------\n"

}

关于最后一个问题:我读取的文件将被其他程序填充和修改。我可以做什么来检测文件违规的情况下,它使一个问题。我不知道什么我的脚本死了。
谢谢

相关问题