Невозможно разделить каждую строку файла CSV в виде массива с помощью Perl - PullRequest
0 голосов
/ 11 марта 2019

Я застрял в проблеме, при которой я анализирую CSV-файл. Файл CSV выглядит как -

CPU Name,DISABLE,Memory,Encoding,Extra Encoding
,b,d,,
String1,YES,1TB,Enabled,Enabled
String2,NO,1TB,Enabled,Enabled
String3,YES,1TB,Enabled,Enabled

Я хочу захватить первые две строки в двух разных массивах. Код, который я использую для этого -

my $row_no =0;
while(my $row=<$fi>){
chomp($row);
$row=~ s/\A\s+//g;
$row=~s/\R//g;
#say $row;
if($row_no==0)
{
    #say $row;
    my @name_initial = split(',',$row);
    say length(@name_initial);
    say @name_initial;
}
elsif($row_no==1)
{
    #say $row;
    @data_type_initial =split(',',$row);
    say length(@data_type_initial);
    say @data_type_initial;
}
$row_no++;
}

Теперь я сформировал два массива из двух верхних строк в файле (@name_initial и @data_type_initial соответственно). Когда я печатаю этот массив, я вижу все 5 значений, но когда я печатаю длину массива, он показывает длину каждый массив как 1. Когда я печатаю элемент, используя индекс массивов, я нахожу каждый элемент на месте, тогда почему он показывает длину как 1. Также второй массив, который сформирован из второй строки CSV-файла, печатается как «bd». Все нулевые значения пропали, и хотя он содержит два значения «b» и «d». Его длина печатается как 1.

Я хочу преобразовать строку файла CSV в массив со всеми значениями null и non_NULL, чтобы я мог выполнять итерации для элементов массива и задавать условия, основанные на нулевых и ненулевых значениях. Как я могу это сделать ???

1 Ответ

4 голосов
/ 11 марта 2019

Посмотрите на perldoc length .Это говорит следующее:

длина EXPR

длина

Возвращает длину в символов от стоимости EXPR.Если EXPR опущен, возвращает длину $_.Если EXPR не определен, возвращает undef.

Эту функцию нельзя использовать для всего массива или хэша, чтобы выяснить, сколько элементов у них есть.Для этого используйте scalar @array и scalar keys %hash соответственно.

Как и все символьные операции Perl, длина обычно имеет дело с логическими символами, а не с физическими байтами.Для того, сколько байтов займет строка, закодированная как UTF-8, используйте length(Encode::encode('UTF-8', EXPR)) (сначала вам нужно будет use Encode).См. Encode и perlunicode.

В частности, бит, который говорит: «Эта функция не может использоваться для всего массива или хэша, чтобы узнать, сколько элементов у них есть. Для этого используйте scalar @array иscalar keys %hash соответственно ".

Так что вы используете здесь неправильный подход.Вместо say length(@array) вам нужно say scalar(@array).

, чтобы объяснить результаты, которые вы получаете.length() ожидает получения скалярного значения (строки) для измерения.Таким образом, он обрабатывает ваш массив как скаляр (эффективно добавляя невидимый вызов к scalar()) и возвращает количество элементов в массиве (равное 5), а length() затем сообщает вам количество элементов в этой строке- 1.

Стоит также отметить, что вам не нужно отслеживать свою собственную переменную $row_no.В Perl есть встроенная переменная с именем $., которая содержит номер текущей записи.

Использование этих знаний (и добавление небольшого пробела) дает нам что-то вроде этого:

while (my $row = <$fi>) {
  chomp($row);

  $row =~ s/\A\s+//g;
  $row =~s/\R//g;

  #say $row;

  if ($. == 0) {
    #say $row;
    my @name_initial = split(/,/, $row);
    say scalar(@name_initial);
    say @name_initial;
  } elsif ($. == 1) {
    #say $row;
    @data_type_initial = split(/,/, $row);
    say scalar(@data_type_initial);
    say @data_type_initial;
  }
}

Обновление: Вы задали пару дополнительных вопросов в конце этого.Я бы посоветовал вам поднять их отдельно.

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