如何忽略Perl中格式错误的JSON字符串

时间:2019-04-30 10:11:05

标签: perl


我的文件夹中有+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 个答案:

答案 0 :(得分:1)

尝试使用evaldecode()捕获异常:

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}

答案 1 :(得分:1)

位置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