Чтение CSV с помощью Perl приводит к искаженным строкам - PullRequest
0 голосов
/ 05 апреля 2019

Я читаю файл CSV с использованием Perl 5.26.1 со строками, которые выглядят следующим образом:

B1_10,202337840166, R08C02,202337840166_R08C02.gtc

I 'Я читаю эти данные в хэш, в котором последний элемент является ключом, а первый - значением.

Я читаю файл построчно (только фрагмент):

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
}

другими словами, последняя строка по какой-то причине обрезается.Я попытался удалить не-ascii символы с $_ =~ s/[[:^ascii:]]//g;, но все равно выдает ту же ошибку.

Я не знаю, почему Perl разрывает эти строки на части: (

Ответы [ 2 ]

5 голосов
/ 05 апреля 2019
while (<$csv>) {
    ...
    chomp;

Я предполагаю, что входной файл имеет конец строки \r\n (стиль Windows), когда вы выполняете код в среде, подобной UNIX (Linux, Mac ...), где конец строки равен \n.Это означает, что $INPUT_RECORD_SEPARATOR также \n и что chomp удаляет только \n и оставляет \r.Слева \r вызывает такой странный вывод.

Чтобы исправить это, либо исправьте окончания строк во входном файле, установите $INPUT_RECORD_SEPARATOR в ожидаемый разделитель, либо просто введите s{\r?\n\z}{} вместо chomp для обработки\r\n и \n окончания строк.

2 голосов
/ 05 апреля 2019

Я запустил ваш фрагмент против вашей строки, и он работал как ожидалось Но у меня было поведение, похожее на то, что вы показываете, потому что в моих данных ложный Control-M.

Попробуйте отфильтровать для контроля-М после того, как ваш chomp замените все control-M командой ниже

s/\cM//g;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...