Как игнорировать искаженную строку JSON в Perl - PullRequest
0 голосов
/ 30 апреля 2019


У меня есть +1000 файлов json в моей папке, и когда я пытаюсь проанализировать данные из этих +1000 файлов, я получаю эту ошибку после анализа +100:

malformed JSON string, neither array, object, number, string or atom, at character offset 0 (before "(end of string)") at -e line 1.

Пожалуйста, как можно игнорировать эту ошибку, пусть команда разбирает все файлы.
Моя команда:

perl -MJSON::XS -CS -0777ne'
   BEGIN { $j = JSON::XS->new->relaxed(1) }
   s/^\(//;  s/\)\z//;
   CORE::say
      join ",",
         map { join ":", $_->{company}, $_->{time} }
            @{ $j->decode($_)->{Companies} }
' *.json

Спасибо

Ответы [ 2 ]

1 голос
/ 30 апреля 2019

Конец строки в позиции 0 означает, что вы передали пустую строку (или undef?). Просто проверьте, пуст ли файл ($_) и пропустите этот файл.

perl -MJSON::XS -CS -0777ne'
   BEGIN { $j = JSON::XS->new->relaxed(1) }
   s/^\(//;  s/\)\z//;
   if (!length($_)) {
      warn("Skipping $ARGV: Empty.\n");
      next;
   }

   CORE::say
      join ",",
         map { join ":", $_->{company}, $_->{time} }
            @{ $j->decode($_)->{Companies} };
' *.json

Вы можете сделать еще один шаг и пропустить все файлы, которые вызывают любые ошибки (что позволяет исправить или обработать их вручную):

perl -MJSON::XS -CS -0777ne'
   BEGIN { $j = JSON::XS->new->relaxed(1) }
   s/^\(//;  s/\)\z//;
   if (!length($_)) {
      warn("Skipping $ARGV: Empty.\n");
      next;
   }

   my $data = eval { $j->decode($_) };
   if (!$data) {
      warn("Skipping $ARGV: $@");
      next;
   }

   CORE::say
      join ",",
         map { join ":", $_->{company}, $_->{time} }
            @{ $data->{Companies} };
' *.json
1 голос
/ 30 апреля 2019

Попробуйте использовать eval, чтобы поймать исключение из decode():

perl -MJSON::XS -CS -0777ne'
   BEGIN { $j = JSON::XS->new->relaxed(1) }
   s/^\(//;  s/\)\z//;
   eval { $j->decode($_) };
   next if $@;
   CORE::say
      join ",",
         map { join ":", $_->{company}, $_->{time} }
            @{ $j->decode($_)->{Companies} }
' *.json

ПРИМЕЧАНИЕ. Если файлы имеют большой размер, вы можете сэкономить время (путемне декодировать файл дважды), сохраняя декодированную переменную в блоке eval: eval { $data = $j->decode($_) } и позже используйте $data->{Companies}

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