我有一个应该是JSON对象的文件,每行一个。不幸的是,在创建文件时发生了通信错误,并且JSON对象之间只有一个空格,而没有换行符。
我需要通过用}\n{替换每个} {实例来解决这个问题。
对于sed或Perl来说应该很容易,对吧?
sed -e "s/}\s{/}\n{/g" file.in > file.out
perl -pe "s/}\s{/}\n{/g" file.in > file.out
但是file.in实际上是4.4 GB,这似乎给这两种解决方案都带来了问题。
sed命令以一个中途正确的文件结束,但是file.out只有335MB,并且只占输入文件的1/10左右,从一行中间截断。这几乎就像是sed在中途退出了。也许它试图将整个4.4 GB的文件加载到内存中,但在大约300MB时耗尽了堆栈空间,并悄悄地杀死了自己。
Perl命令出错,并显示以下消息:
[1] 2904 segmentation fault perl -pe "s/}\s{/}\n{/g" file.in > file.out
我还应该尝试什么?
发布于 2017-06-29 03:50:26
Perl中默认的输入记录分隔符是\n,但是您可以根据需要将其更改为任何字符。对于这个问题,你可以使用{ (八进制173)。
perl -0173 -pe 's/}\s{/}\n{/g' file.in > file.out发布于 2017-06-29 04:33:12
与早期的解决方案不同,这个解决方案处理{"x":"} {"}。
use strict;
use warnings;
use feature qw( say );
use JSON::XS qw( );
use constant READ_SIZE => 64*1024*1024;
my $j_in = JSON::XS->new->utf8;
my $j_out = JSON::XS->new;
binmode STDIN;
binmode STDOUT, ':encoding(UTF-8)';
while (1) {
my $rv = sysread(\*STDIN, my $block, READ_SIZE);
die($!) if !defined($rv);
last if !$rv;
$j_in->incr_parse($block);
while (my $o = $j_in->incr_parse()) {
say $j_out->encode($o);
}
}
die("Bad data") if $j_in->incr_text !~ /^\s*\z/;发布于 2017-06-29 03:49:18
perl -ple 'BEGIN{$/=qq/} {/;$\=qq/}\n{/}undef$\ if eof' <input >outputhttps://stackoverflow.com/questions/44811130
复制相似问题