在Perl中使用双引号解析制表符分隔文件

时间:2011-01-03 12:30:16

标签: perl parsing csv perl-module text-parsing

我有一个数据集,用双引号中的用户代理字符串分隔。我需要解析每个列,并根据我使用Text :: CSV模块的other post的答案。

94410634  0   GET  "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; GTB6.6; .NET CLR 2.0.50727; .NET CLR 3.0.04506.648; .NET CLR 3.5.21022; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729; AskTB5.5)"   1

代码很简单。

#!/usr/bin/perl

use strict;
use warnings;
use Text::CSV;

my $csv = Text::CSV->new(sep_char => "\t");

    while (<>) {
        if ($csv->parse($_)) {
            my @columns = $csv->fields();
            print "@columns\n";
        } else {
            my $err = $csv->error_input;
            print "Failed to parse line: $err";
        }
    }

但是当我在这个数据集上尝试时,我收到了Failed to parse line:错误。我究竟做错了什么?我需要提取包含用户代理字符串的第4列以供进一步处理。

1 个答案:

答案 0 :(得分:6)

  1. 您的构造函数参数应该在hashref中,而不是哈希:

    my $ csv = Text :: CSV-&gt; new({sep_char =&gt;“\ t”});

  2. 您确定数据集完全符合您的想法吗?可能是某个地方缺少双引号或者没有标签?

    要验证文件内容,您是在Unix / Linux还是Windows?在unix上,请运行:cat -vet my_log_file_name | head -3并检查输出是否有空格或“^ I”序列,您希望选项卡。 cat -vet将所有特殊字符打印为特殊可打印序列(TAB =&gt; ^I,换行符=&gt; $等等。)

    < / LI>

    以下测试在我的ActivePerl上完美运行:

    #!/usr/bin/perl
    use strict;
    use warnings;
    use Text::CSV;
    
    my $s = qq[94410634\t0\tGET\t"Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; GTB6.6; .NET CLR 2.0.50727; .NET CLR 3.0.04506.648; .NET CLR 3.5.21022; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729; AskTB5.5)"\t1\n];;
    my $csv = Text::CSV->new({sep_char => "\t"});
    
    if ($csv->parse($s)) {
        my @columns = $csv->fields();
        print "c=$columns[3]\n";
    } else {
        my $err = $csv->error_input;
        print "Failed to parse line: $err";
    }
    

    <强>输出

    C:\> perl d:\scripts\test4.pl
    c=Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; GTB6.6; ...