Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Regex 在Perl中使用Text::CSV解析以制表符分隔的文件_Regex_Perl_Parsing_Tab Delimited_Tab Delimited Text - Fatal编程技术网

Regex 在Perl中使用Text::CSV解析以制表符分隔的文件

Regex 在Perl中使用Text::CSV解析以制表符分隔的文件,regex,perl,parsing,tab-delimited,tab-delimited-text,Regex,Perl,Parsing,Tab Delimited,Tab Delimited Text,我试图利用Text::CSVPerl模块来解析以制表符分隔的文件 我试图分析的文件是: #IGNORE COLUMN1 COLUMN2 COLUMN3 COLUMN4 ROW1 x y z a ROW2 b c d ROW3 w 请注意,该文件是以制表符分隔的。此文件可能有N列和N行。此外,在行2的情况下,它有第四个选项卡,但没有值第3行在第1列的w值之后没有选项卡。即,某些列可能有未定义的值或空白值 到目前为止,我已经开始编写一个Perl脚本,但很

我试图利用
Text::CSV
Perl模块来解析以制表符分隔的文件

我试图分析的文件是:

#IGNORE COLUMN1 COLUMN2 COLUMN3 COLUMN4
ROW1    x   y   z   a
ROW2    b   c   d   
ROW3    w
请注意,该文件是以制表符分隔的。此文件可能有
N
列和
N
行。此外,在
行2
的情况下,它有第四个选项卡,但没有值<代码>第3行在
第1列
w
值之后没有选项卡。即,某些列可能有未定义的值或空白值

到目前为止,我已经开始编写一个Perl脚本,但很早就开始尝试找出如何编写代码来回答以下问题:

找出ROWn有多少个
。然后针对每个
列n
检查是否有
ROWn
值。因此,在本例中,
COLUMN2
COLUMN3
COLUMN4
将缺少值

任何提示和指导都会有所帮助(我是Perl新手)。我已经查看了CPAN Text::CSV页面,但还没有设法解决这个问题

#!/usr/bin/perl
use warnings;
use strict;
use v5.12;
use Text::CSV;

my $csv = Text::CSV->new ({
     escape_char         => '"',
     sep_char            => '\t',
     eol                 => $\,
     binary              => 1,
     blank_is_undef      => 1,
     empty_is_undef      => 1,
     });

open (my $file, "<", "tabfile.txt") or die "cannot open: $!";
while (my $row = $csv->getline ($file)) {
    say @$row[0];
}
close($file);
#/usr/bin/perl
使用警告;
严格使用;
使用v5.12;
使用Text::CSV;
my$csv=文本::csv->新建({
转义字符=>“”,
sep_char=>'\t',
下线=>$\,
二进制=>1,
空白_为_未定义=>1,
空_是_unde=>1,
});

打开(我的$file,“一种方法,其中每行处理每个字段,并在不为
false
时增加一个计数器:

#!/usr/bin/env perl

use warnings;
use strict;
use Text::CSV_XS;

my (@col_counter); 
my ($line_counter, $r, $num_cols) = (0, 0, 0); 

open my $fh, '<', shift or die;

my $csv = Text::CSV_XS->new({
    sep_char => qq|\t|
});

while ( my $row = $csv->getline( $fh ) ) { 
    ## First row (header), get the number of columns.
    if ( $line_counter == 0 ) { 
        $num_cols = $#$row;
        next;
    }
    ## For each data row, traverse every column and increment a 
    ## counter if it has any value.
    for ( 1 .. $#$row ) { 
        ++$col_counter[ $_ ] if $row->[ $_ ];
    }   
}
continue {
    $line_counter++;
}

printf qq|Lines of file: %d\n|, $line_counter - 1;
## Check if any column has missing values. For each column compare the 
## number of lines read (substract 1 of header) with its counter. If they
## are different it means that the column had any row without value.
for my $i ( 1 .. $num_cols ) { 
    $r = $line_counter - 1 - (defined $col_counter[ $i ] ? $col_counter[ $i ] : 0); 
    if ( $r > 0 ) { 
        printf qq|Column %d has %d missing values\n|, $i, $r;  
    }   
}
这将产生:

Lines of file: 3
Column 2 has 1 missing values
Column 3 has 1 missing values
Column 4 has 2 missing values

更新:查看注释。我反向查找不包含任何值并将当前行号附加到数组中的列,然后使用
join
提取所有行

我更改了哪些部分?这里保存行号

for ( 1 .. $num_cols ) { 
    push @{ $col_counter[ $_ ] }, $line_counter unless $row->[ $_ ];
}
在这里打印出来。你需要评论一下以前的行为

if ( defined $col_counter[ $i ] ) { 
    printf qq|Column %d has no value in lines %s\n|, $i, join q|,|, @{ $col_counter[ $i ] };
}
它产生:

Lines of file: 3
Column 2 has no value in lines 3
Column 3 has no value in lines 3
Column 4 has no value in lines 2,3

如果您可以同时拥有空白字段(一行中有多个制表符)和不存在的字段(行尾过早),您会将空白字段计算为与不存在字段相同的值吗?@TLP Yes。基本上,一行可能有多个制表符,其中值为“空白”(例如,在
ROW2
COLUMN4
中有一个“空”制表符值或行可能会过早结束,就像在
ROW3
中那样,在
COLUMN1
中的
w
后面没有字符,请使用
sep\u char=>“\t”
作为
'\t'
使分隔符按字面意思是
\t
而不是制表符。@user2402135那么您有什么问题?您不知道如何计算
$row
的元素?您不知道如何比较空的和未定义的?@TLP从查看Text::CSV CPAN页面可以看出,我不能o访问每个行x列引用,以便能够比较空的和未定义的,或者能够计算行中的元素。如果我能够找到/访问组成制表符分隔表的“元素”,那么我可以轻松地继续:)当我的文件如下所示时,此代码似乎不起作用:
#忽略COLUMN1 COLUMN2 COLUMN3 COLUMN4 row1 x x x row2。
不知道
COLUMN4
@user2402135:在您的输入文件
COLUMN4
中缺少两个值。我不理解您的示例。如果我更改上面的输入文件,请不要这样做hat
COLUMN4
没有任何行值,那么在打印缺少的值时会忽略整个列。我希望能够打印
COLUMN4
N
缺少的值,如果它有零值。目前,如果它根本没有值,代码只会忽略
COLUMN4
。@user2402135:我已经修复了它从标题中提取列数。现在我似乎完全崩溃了。我甚至无法识别任何缺少的值。
Lines of file: 3
Column 2 has no value in lines 3
Column 3 has no value in lines 3
Column 4 has no value in lines 2,3