用Perl读取CSV会产生扭曲的行

时间:2019-04-05 19:47:25

标签: perl

我正在使用Perl 5.26.1读取CSV文件,其行如下所示:

  

B1_10,202337840166,R08C02,202337840166_R08C02.gtc

我正在将这些数据读取到一个哈希中,该哈希的最后一个元素为键,第一个为值。

我逐行读取文件(仅摘要):

while (<$csv>) {
    if (/^Sample/) { next }
    say "-----start----\noriginal = $_";
    chomp;
    my @line = split /,/;
    my $name = $line[0];
    my $vcf  = $line[3];
    say "1st element = $name";
    say "4th element = $vcf";
    $vcf2dir{$vcf} = $name;
    say "\$vcf2dir{$vcf} = '$name'";
    say '-----end------';
}

产生以下输出:

-----start----
original = B1_10,202337840166,R08C02,202337840166_R08C02.gtc

1st element = B1_10
4th element = 202337840166_R08C02.gtc
} = 'B1_10'2337840166_R08C02.gtc
-----end-------

但它看起来应该像

-----start----
original = B1_10,202337840166,R08C02,202337840166_R08C02.gtc

1st element = B1_10
4th element = 202337840166_R08C02.gtc
$vcf2dir{202337840166_R08C02.gtc} = 'B1_10'
-----end-------

它与数据打印机软件包奇怪地显示:

use DDP;
p %vcf2dir;

产生

{
'   "B1_10"840166_R08C02.gtc
}

换句话说,由于某种原因,最后一个字符串被截断。 我尝试使用$_ =~ s/[[:^ascii:]]//g;删除非ASCII字符,但这仍然会产生相同的错误。

我不知道为什么Perl会将这些字符串撕开:(

2 个答案:

答案 0 :(得分:5)

while (<$csv>) {
    ...
    chomp;

我的猜测是,当您在UNIX之类的环境(Linux,Mac ...)中执行代码时,输​​入文件的行尾为\r\n(Windows风格),而行尾为{{1 }}。这意味着\n也是$INPUT_RECORD_SEPARATOR,而\n仅删除chomp并保留\n。左边的\r会导致这种奇怪的输出。

要解决此问题,请修复输入文件中的行尾,将\r设置为预期的分隔符,或者只执行$INPUT_RECORD_SEPARATOR而不是s{\r?\n\z}{}来处理chomp\r\n行尾。

答案 1 :(得分:2)

我将您的代码段贴在您的行上,它按预期运行 但是我的行为就像您显示的那样,因为我的数据中存在一个虚假的Control-M。

尝试过滤Control-M 在您的chomp后,用下面的命令替换所有control-M

s/\cM//g;