perl - 读取带有嵌入换行符的 CSV 文件

标签 perl csv newline

我正在处理从网站上抓取的文件,该文件保存为带有引号字段的分号 csv。 最后一个字段包含嵌入的换行符。 我一直在研究一个脚本来处理文件。 我对 perl 还很陌生,起初是用普通的 perl 脚本尝试它,但很快发现它不起作用。 我做了研究,发现我应该改用 Text::CSV 模块。我遇到了这些解释如何使用该模块的网站:

http://perlmaven.com/how-to-read-a-csv-file-using-perl

http://perlmeme.org/tutorials/parsing_csv.html

http://metacpan.org/pod/Text::CSV#Embedded-newlines

基本上我想要完成的是正确读取文件,以便所有字段都正确分隔,而不是在换行符处中断。然后从该字段中删除换行符并将其写入新文件。

这是原始数据的示例:

 "2030";"NH Amersfoort";"Stationsstraat 75";"3811 MH AMERSFOORT";"033-4221200";"www.nh-hotels.nl";"52.154316";"5.380036";"<UL class=stars><LI>
 <LI>
 <LI>
 <LI></LI></UL>"
 "2031";"NH Amsterdam Centre";"Stadhouderskade 7";"1054 ES AMSTERDAM";"020-6851351";"www.nh-hotels.com";"52.363075";"4.879458";"<UL class=stars><LI>
 <LI>
 <LI>
 <LI></LI></UL>"
 "2032";"NH Atlanta Rotterdam Hotel";"Aert van Nesstraat 4";"3012 CA ROTTERDAM";"010-2067800";"www.nh-hotels.com";"51.921028";"4.478619";"<UL class=stars><LI>
 <LI>
 <LI>
 <LI></LI></UL>" 

我想要的是:

 "2030";"NH Amersfoort";"Stationsstraat 75";"3811 MH AMERSFOORT";"033-4221200";"www.nh-hotels.nl";"52.154316";"5.380036";"<UL class=stars><LI><LI><LI><LI></LI></UL>"
 "2031";"NH Amsterdam Centre";"Stadhouderskade 7";"1054 ES AMSTERDAM";"020-6851351";"www.nh-hotels.com";"52.363075";"4.879458";"<UL class=stars><LI><LI><LI><LI></LI></UL>"
 "2032";"NH Atlanta Rotterdam Hotel";"Aert van Nesstraat 4";"3012 CA ROTTERDAM";"010-2067800";"www.nh-hotels.com";"51.921028";"4.478619";"<UL class=stars><LI><LI><LI><LI></LI></UL>" 

到目前为止,这是我的完整脚本。我尝试了 10 种不同的选择和建议,但它们都不起作用!

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

 my $inputfile  = shift || die "Give input and output names!\n";
 my $outputfile = shift || die "Give output name!\n";

 open my $infile,  '<', $inputfile   or die "Sourcefile in use / not found :$!\n";
 open my $outfile, '>', $outputfile  or die "Outputfile in use :$!\n";

    my $csv = Text::CSV->new ({
binary => 1,
sep_char => ';'
});

while (my $elements = $csv->getline( $infile )) {
        my $stars = $elements->[8];
        #$ster =~ s/[\r\n]//g
        print "$stars\n\n";
        }

 close $infile;
 close $outfile;

这会正确地打印带有换行符的字段,但并没有将它们移除。我怎么做?使用正则表达式替换换行符不起作用。下一个问题是我什么时候弄清楚如何清理该字段。我如何打印新文件?

最佳答案

我不确定你在这里问什么,因为你似乎已经有了答案。但是,此代码确实有效:

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

my $csv = Text::CSV->new ({
    binary => 1,
    sep_char => ';',
    eol => $/,                # to make $csv->print use newlines
    always_quote => 1,        # to keep your numbers quoted
});

while (my $row = $csv->getline( *DATA )) {
    $row->[8] =~ s/[\r\n]+//g;
    $csv->print(*STDOUT, $row);
}

__DATA__
"2030";"NH Amersfoort";"Stationsstraat 75";"3811 MH AMERSFOORT";"033-4221200";"www.nh-hotels.nl";"52.154316";"5.380036";"<UL class=stars><LI>
<LI>
<LI>
<LI></LI></UL>"
"2031";"NH Amsterdam Centre";"Stadhouderskade 7";"1054 ES AMSTERDAM";"020-6851351";"www.nh-hotels.com";"52.363075";"4.879458";"<UL class=stars><LI>
<LI>
<LI>
<LI></LI></UL>"
"2032";"NH Atlanta Rotterdam Hotel";"Aert van Nesstraat 4";"3012 CA ROTTERDAM";"010-2067800";"www.nh-hotels.com";"51.921028";"4.478619";"<UL class=stars><LI>
<LI>
<LI>
<LI></LI></UL>"

指针:

eol 选项与 Text::CSV 的打印一起使用可以使它按照您的预期进行,即打印换行符。我使用 STDOUT 作为输出句柄,但您可以使用任何您想要的文件句柄。

我不知道为什么你说替换对你“不起作用”,但我怀疑你可能做了这样的事情:

my $foo = $row->[8];
$foo =~ s/[\r\n]//g;
print @$row;

这不会更改 $row 中的值,只会更改 $foo 中的副本。

关于perl - 读取带有嵌入换行符的 CSV 文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14396605/

相关文章:

macos - 如何在 macos 上安装 perl 模块?

python - 解析 JSON Lines 文件

java - 在Java中生成文本文件时应该使用 "\r\n"还是 "\n"?

c++ - 访问 ".txt"文件中的信息并转到确定的行

python - .write() 中的变量后面的字符串部分被放在 Python 中的新行上

perl - PDL::Core 和 PDL::Core 之间的区别 ':Internal'

perl - 使用不同的用户名和密码将文件复制到网络共享

perl - 使用哈希或数组元素时如何绕过魔术钩子(Hook)

python - 如何在 Python 上将列表的所有值导出到 csv

MySQL加载忽略一些记录