2016-01-17 79 views
0

我的JSON對象(超過12000行)一個大文件看起來像名稱:分裂一個大的JSON文件和設置輸出文件

{ 
    "System": "2334", 
    "Id": "AP64531346-2016055553824", 
    "dtis": "106165099", 
    "Type": "Up", 
    ... (in total, 112 lines per record) 
} 
{ 
    "System": "873", 
    "Id": "AP24531346-20160676553824", 
    "dtis": "1261699", 
    "Type": "Up", 
    ... (in total, 112 lines per record) 
} 

我要拆小的大文件每一個文件夾都有一個入口(112行),並將每個片段的名稱設置爲「Id」的值,我的意思分別是例如AP64531346-2016055553824.txt和AP24531346-20160676553824。

我嘗試過使用GNU Split,但是我無法將每個文件的名稱設置爲ID加上.txt。

split -l 112 ../bigfile.csv 

有什麼建議嗎?

回答

2

在兩個步驟:首先你生成一般命名的文件與

split -l 112 ../bigfile.csv 

現在你有一個名爲xaaxab等文件,我認爲這些都是在目錄中唯一的文件。現在,您可以循環過去了,提取標識並重新命名:

for file in *; do 
    newname="$(grep -m 1 -Po '(?<="Id": ")[^"]+' "$file")" 
    mv "$file" "$newname.txt" 
done 

grep -o只提取了比賽,並且採用了零寬度「向後看」來獲得ID線。只有在使用Perl正則表達式引擎(-P)時才能使用瀏覽功能。 -m 1在第一場比賽後停止,所以當你知道第一場比賽足夠好的時候,你不會瀏覽整個文件。

當每塊沒有112行時,這當然會壞掉– a proper solution會解析文件。

2

這聽起來像你想把每個JSON文件放在它自己的文件中。你可以使用JSON :: XS的增量分析器來做到這一點。

use JSON::XS qw(); 

my $json = JSON::XS->utf8->new(); 

local $/ = \(1024*1024) 
while (<>) { 
    for my $obj ($json->incr_parse($_)) { 
     my $id = $obj->{Id}; 
     open(my $fh, '>', $id . ".txt") 
     or die $!; 
     print($fh $json->encode($obj)); 
    } 
} 
+2

請注意,這將導致數據中的鍵以不同於原來的順序出現。如果數據實際上與描述相同,則可能比'$/=「\ n}更好\ n」; while(my $ record = <>){my $ id = $ json-> decode($ record) - > {Id};打開(我的$ fh,...)或死亡;打印$ fh $記錄}'(僅在錯誤檢查時) – ysth

+0

@ysth,正確,但按鍵順序在JSON中沒有意義。至於評論的其餘部分,你爲什麼不把它作爲答案發布? – ikegami

+0

與您的看起來有點太不一樣 – ysth

1

的一般方法到任務(即,一種方法,使得沒有關於JSON實體在輸入文件中的流的假設,比它們是有效的JSON實體其他)由以下示出的「單襯裏「:

jq -cr '"\(.Id)\t\(.)"' | awk -F\\t '{print $2 > "/tmp/"$1".json"}' 

這裏使用了‘JSON查詢’(jq)命令行處理器,其可在許多平臺上。

如果您希望每個新文件是相當打印,那麼你可以在第二個步驟中使用JQ對於爲好,如:

ls *.json | while read f ; do jq . "$f" > "$f.tmp" && mv "$f.tmp" "$f" ; done 
+0

您知道OP發佈的內容無效JSON,但評估者將多個合法的JSON片段合併到一個文件中? – andlrc

+0

你知道我在編輯帖子之前,在你評論前11個小時左右? – peak

1

JSON結構是用Perl數據結構,高度兼容快速的方式來分離記錄在不同的文件可以使用eval。考慮到你json沒有在值中保存「:」

local $/ = undef; 
open FILE, "Testjson.txt" or die "Couldn't open file: $!"; 
my $string = <BiGFILE>; 
close FILE; 
$string =~ s/:/,/g; 
$jsonStr = eval $string; 

foreach my $record (@{$jsonStr}) { 
print $record->{'Id'} . "\n"; 
}